Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
matrix:
os: [ubuntu-latest]
php: [8.1, 8.2]
laravel: ['^9.0', '^10.0']
laravel: ['^9.12', '^10.0']
stability: [prefer-lowest, prefer-stable]

name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ${{ matrix.os }}
Expand Down
6 changes: 3 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
],
"require": {
"php": "^8.0",
"illuminate/contracts": "^9.0|^10.0",
"illuminate/support": "^9.0|^10.0",
"illuminate/http": "^9.0|^10.0",
"illuminate/contracts": "^9.12|^10.0",
"illuminate/support": "^9.12|^10.0",
"illuminate/http": "^9.12|^10.0",
"symfony/process": "^6.0"
},
"require-dev": {
Expand Down
5 changes: 5 additions & 0 deletions config/language-recognizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,10 @@
// 'exclude' => ['cat','sot','kat','bcl','glg','lao','lit','umb','tsn','vec','nso','ban','bug','knc','kng','ibb','lug','ace','bam','tzm','ydd','kmb','lun','shn','war','dyu','wol','nds','mkd','vmw','zgh','ewe','khk','slv','ayr','bem','emk','bci','bum','epo','pam','tiv','tpi','ven','ssw','nyn','kbd','iii','yao','lav','quz','src','rup','sco','tso','rmy','men','fon','nhn','dip','kde','snn','kbp','tem','toi','est','snk','cjk','ada','aii','quy','rmn','bin','gaa','ndo'],
],

'deepl' => [
'host' => env('LANGUAGE_RECOGNIZER_DEEPL_HOST', 'https://api-free.deepl.com'),
'key' => env('LANGUAGE_RECOGNIZER_DEEPL_KEY', null),
],

]
];
3 changes: 3 additions & 0 deletions src/Commands/InstallLocalRecognizerCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ protected function getOs()

protected function getDownloadPath()
{
/**
* @var string
*/
$pathOption = $this->option('path');

if ($pathOption) {
Expand Down
68 changes: 68 additions & 0 deletions src/Drivers/DeeplLanguageRecognizerDriver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

namespace Oneofftech\LaravelLanguageRecognizer\Drivers;

use Exception;
use Illuminate\Support\Facades\Http;
use InvalidArgumentException;
use Oneofftech\LaravelLanguageRecognizer\Contracts\LanguageRecognizer;

class DeeplLanguageRecognizerDriver implements LanguageRecognizer
{
protected string $host;

protected string $token;

public function __construct($config)
{
if (empty($config['host'] ?? null)) {
throw new InvalidArgumentException("Invalid host");
}

if (empty($config['key'] ?? null)) {
throw new InvalidArgumentException("Invalid authentication key");
}

if (empty(trim($config['host']))) {
throw new InvalidArgumentException("Invalid host");
}

if (empty(trim($config['key']))) {
throw new InvalidArgumentException("Invalid authentication key");
}

$this->host = rtrim($config['host'], '/');
$this->token = $config['key'];
}

/**
* @inherit
*/
public function recognize($text, $limit = 2): array
{
$response = Http::acceptJson()
->asForm()
->withToken($this->token, 'DeepL-Auth-Key')
->post("{$this->host}/v2/translate", [
'text' => $text,
'target_lang' => 'EN-US',
])
->throw();

$json = $response->json();

$detectedLanguage = $json['translations'][0]['detected_source_language'] ?? null;

if (is_null($detectedLanguage)) {
throw new Exception('Failed to obtain detected language from DeepL API');
}

if (in_array($detectedLanguage, ['EN-US', 'EN-GB'])) {
$detectedLanguage = 'EN';
}

return [
$detectedLanguage => 1.0,
];
}
}
11 changes: 11 additions & 0 deletions src/LaravelLanguageRecognizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Oneofftech\LaravelLanguageRecognizer;

use Illuminate\Support\Manager;
use Oneofftech\LaravelLanguageRecognizer\Drivers\DeeplLanguageRecognizerDriver;
use Oneofftech\LaravelLanguageRecognizer\Drivers\LocalLanguageRecognizerDriver;

/**
Expand Down Expand Up @@ -36,6 +37,16 @@ protected function createLocalDriver()
return new LocalLanguageRecognizerDriver($this->container['config']['language-recognizer.drivers.local']);
}

/**
* @return \Oneofftech\LaravelLanguageRecognizer\Drivers\DeeplLanguageRecognizerDriver
*
* @psalm-suppress UndefinedInterfaceMethod
*/
protected function createDeeplDriver()
{
return new DeeplLanguageRecognizerDriver($this->container['config']['language-recognizer.drivers.deepl']);
}

/**
* Get the default driver name.
*
Expand Down
62 changes: 62 additions & 0 deletions tests/Integration/DeeplLanguageRecognizerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

namespace Oneofftech\LaravelLanguageRecognizer\Tests\Unit;

use Illuminate\Http\Client\Request;
use Illuminate\Support\Facades\Http;
use InvalidArgumentException;
use Oneofftech\LaravelLanguageRecognizer\Drivers\DeeplLanguageRecognizerDriver;
use Oneofftech\LaravelLanguageRecognizer\Tests\Integration\TestCase;

class DeeplLanguageRecognizerTest extends TestCase
{
/** @test */
public function throws_if_host_empty()
{
$this->expectException(InvalidArgumentException::class);

new DeeplLanguageRecognizerDriver([
'host' => ' ',
'key' => 'a-value',
]);
}

/** @test */
public function throws_if_key_empty()
{
$this->expectException(InvalidArgumentException::class);

new DeeplLanguageRecognizerDriver([
'key' => ' ',
'host' => 'https://a-domain',
]);
}

/** @test */
public function it_can_recognize_a_string()
{
Http::preventStrayRequests();

Http::fake([
'https://api-free.deepl.com/*' => Http::response('{"translations": [{"detected_source_language": "EN","text": "This should be an english string"}]}', 200),
]);


$driver = new DeeplLanguageRecognizerDriver([
'key' => 'a-value',
'host' => 'https://api-free.deepl.com',
]);

$languages = $driver->recognize('This should be an english string');

$this->assertEquals([
"EN" => 1.0,
], $languages);

Http::assertSent(function (Request $request) {
return $request->url() == 'https://api-free.deepl.com/v2/translate' &&
$request['text'] == 'This should be an english string' &&
$request['target_lang'] === 'EN-US';
});
}
}
13 changes: 13 additions & 0 deletions tests/Integration/LaravelLanguageRecognizerFacadeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Oneofftech\LaravelLanguageRecognizer\Tests\Integration;

use Oneofftech\LaravelLanguageRecognizer\Drivers\DeeplLanguageRecognizerDriver;
use Oneofftech\LaravelLanguageRecognizer\Drivers\LocalLanguageRecognizerDriver;
use Oneofftech\LaravelLanguageRecognizer\Support\Facades\LanguageRecognizer;

Expand All @@ -18,6 +19,18 @@ public function default_local_driver_can_be_obtained()
$this->assertInstanceOf(LocalLanguageRecognizerDriver::class, $service);
}

/** @test */
public function deepl_driver_can_be_obtained()
{
$this->app['config']->set('language-recognizer.default', 'deepl');
$this->app['config']->set('language-recognizer.drivers.deepl.host', 'https://api-free.deepl.com');
$this->app['config']->set('language-recognizer.drivers.deepl.key', 'a-key');

$service = LanguageRecognizer::driver('deepl');

$this->assertInstanceOf(DeeplLanguageRecognizerDriver::class, $service);
}

/** @test */
public function recognition_can_be_done_from_facade()
{
Expand Down