summaryrefslogtreecommitdiff
path: root/www/wiki/extensions/Translate/webservices/MicrosoftWebService.php
diff options
context:
space:
mode:
Diffstat (limited to 'www/wiki/extensions/Translate/webservices/MicrosoftWebService.php')
-rw-r--r--www/wiki/extensions/Translate/webservices/MicrosoftWebService.php142
1 files changed, 142 insertions, 0 deletions
diff --git a/www/wiki/extensions/Translate/webservices/MicrosoftWebService.php b/www/wiki/extensions/Translate/webservices/MicrosoftWebService.php
new file mode 100644
index 00000000..221944d5
--- /dev/null
+++ b/www/wiki/extensions/Translate/webservices/MicrosoftWebService.php
@@ -0,0 +1,142 @@
+<?php
+/**
+ * Contains a class for querying external translation service.
+ *
+ * @file
+ * @author Niklas Laxström
+ * @author Ulrich Strauss
+ * @license GPL-2.0-or-later
+ */
+
+/**
+ * Implements support for Microsoft translation api v3.
+ * @see https://docs.microsoft.com/fi-fi/azure/cognitive-services/Translator/reference/v3-0-reference
+ * @ingroup TranslationWebService
+ * @since 2013-01-01
+ */
+class MicrosoftWebService extends TranslationWebService {
+ public function getType() {
+ return 'mt';
+ }
+
+ protected function mapCode( $code ) {
+ $map = [
+ 'tl' => 'fil',
+ 'zh-hant' => 'zh-Hant',
+ 'zh-hans' => 'zh-Hans',
+ 'sr-ec' => 'sr-Cyrl',
+ 'sr-el' => 'sr-Latn',
+ 'pt-br' => 'pt',
+ ];
+
+ return $map[$code] ?? $code;
+ }
+
+ protected function doPairs() {
+ if ( !isset( $this->config['key'] ) ) {
+ throw new TranslationWebServiceConfigurationException( 'key is not set' );
+ }
+
+ $key = $this->config['key'];
+
+ $options = [];
+ $options['method'] = 'GET';
+ $options['timeout'] = $this->config['timeout'];
+
+ $url = $this->config['url'] . '/languages?api-version=3.0';
+
+ $req = MWHttpRequest::factory( $url, $options );
+ $req->setHeader( 'Ocp-Apim-Subscription-Key', $key );
+
+ $status = $req->execute();
+ if ( !$status->isOK() ) {
+ $error = $req->getContent();
+ // Most likely a timeout or other general error
+ throw new TranslationWebServiceException(
+ 'Http::get failed:' . serialize( $error ) . serialize( $status )
+ );
+ }
+
+ $json = $req->getContent();
+ $response = json_decode( $json, true );
+ if ( !isset( $response[ 'translation' ] ) ) {
+ throw new TranslationWebServiceException(
+ 'Unable to fetch list of available languages: ' . $json
+ );
+ }
+
+ $languages = array_keys( $response[ 'translation' ] );
+
+ // Let's make a cartesian product, assuming we can translate from any language to any language
+ $pairs = [];
+ foreach ( $languages as $from ) {
+ foreach ( $languages as $to ) {
+ $pairs[$from][$to] = true;
+ }
+ }
+
+ return $pairs;
+ }
+
+ protected function getQuery( $text, $from, $to ) {
+ if ( !isset( $this->config['key'] ) ) {
+ throw new TranslationWebServiceConfigurationException( 'key is not set' );
+ }
+
+ $key = $this->config['key'];
+ $text = trim( $text );
+ $text = $this->wrapUntranslatable( $text );
+
+ $url = $this->config['url'] . '/translate';
+ $params = [
+ 'api-version' => '3.0',
+ 'from' => $from,
+ 'to' => $to,
+ 'textType' => 'html',
+ ];
+ $headers = [
+ 'Ocp-Apim-Subscription-Key' => $key,
+ 'Content-Type' => 'application/json',
+ ];
+ $body = json_encode( [ [ 'Text' => $text ] ] );
+
+ if ( strlen( $body ) > 5000 ) {
+ throw new TranslationWebServiceInvalidInputException( 'Source text too long' );
+ }
+
+ return TranslationQuery::factory( $url )
+ ->timeout( $this->config['timeout'] )
+ ->queryParameters( $params )
+ ->queryHeaders( $headers )
+ ->postWithData( $body );
+ }
+
+ protected function parseResponse( TranslationQueryResponse $reply ) {
+ $body = $reply->getBody();
+
+ $response = json_decode( $body, true );
+ if ( !isset( $response[ 0 ][ 'translations' ][ 0 ][ 'text' ] ) ) {
+ throw new TranslationWebServiceException(
+ 'Unable to parse translation response: ' . $body
+ );
+ }
+
+ $text = $response[ 0 ][ 'translations' ][ 0 ][ 'text' ];
+ $text = $this->unwrapUntranslatable( $text );
+
+ return $text;
+ }
+
+ /// Override from parent
+ protected function wrapUntranslatable( $text ) {
+ $pattern = '~%[^% ]+%|\$\d|{VAR:[^}]+}|{?{(PLURAL|GRAMMAR|GENDER):[^|]+\||%(\d\$)?[sd]~';
+ $wrap = '<span class="notranslate">\0</span>';
+ return preg_replace( $pattern, $wrap, $text );
+ }
+
+ /// Override from parent
+ protected function unwrapUntranslatable( $text ) {
+ $pattern = '~<span class="notranslate">\s*(.*?)\s*</span>~';
+ return preg_replace( $pattern, '\1', $text );
+ }
+}