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
59 changes: 54 additions & 5 deletions src/app/Console/Commands/TranslateShortDescriptionJapanese.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ class TranslateShortDescriptionJapanese extends Command
*/
protected $signature = 'world-heritage:translate-short-description-japanese
{--force : Allow execution outside local environment}
{--dry-run : Skip DB writes and API calls}';
{--dry-run : Skip DB writes and API calls}
{--from-json : Use translation JSON instead of calling API}';

/**
* The console command description.
Expand Down Expand Up @@ -46,6 +47,23 @@ public function handle(): int
$total = count($sites);
$this->info("Total sites: {$total}");

$fromJson = (bool) $this->option('from-json');

// Load translation map from JSON if --from-json is specified
$translationMap = [];
if ($fromJson) {
$translationPath = storage_path('app/private/unesco/world_heritage_sites_translation.json');
if (!file_exists($translationPath)) {
$this->error("Translation JSON not found: {$translationPath}");
return 1;
}
$translationData = json_decode(file_get_contents($translationPath), true);
foreach ($translationData['results'] as $item) {
$translationMap[$item['id_no']] = $item;
}
$this->info("Loaded translation JSON: " . count($translationMap) . " records");
}

$bar = $this->output->createProgressBar($total);
$bar->start();

Expand All @@ -59,11 +77,9 @@ public function handle(): int
continue;
}

// DBに翻訳済みのものがあればそこから取得してJSONに反映
// if translated columns are existed in DB, fetching from there and reflected on Json File
// If already translated in DB, fetch from there and reflect on JSON file
$record = WorldHeritageDescription::where('world_heritage_site_id', $idNo)
->whereNotNull('short_description_ja')
->whereNotNull('description_ja')
->first();

if ($record) {
Expand All @@ -73,12 +89,44 @@ public function handle(): int
continue;
}

// If --from-json is specified, use translation JSON instead of calling API
if ($fromJson) {
$translated = $translationMap[$idNo] ?? null;
if (!$translated) {
$this->newLine();
$this->warn("No translation found in JSON for id_no={$idNo}, skipping.");
$bar->advance();
continue;
}

$shortDescriptionJa = $translated['short_description_ja'] ?? null;
$descriptionJa = $translated['description_ja'] ?? null;

if (!$this->option('dry-run')) {
WorldHeritageDescription::updateOrCreate(
['world_heritage_site_id' => $idNo],
[
'short_description_en' => $shortDescriptionEn,
'short_description_ja' => $shortDescriptionJa,
'description_en' => $descriptionEn,
'description_ja' => $descriptionJa,
]
);
}

$sites[$index]['short_description_ja'] = $shortDescriptionJa;
$sites[$index]['description_ja'] = $descriptionJa;
$bar->advance();
continue;
}

if ($this->option('dry-run')) {
$this->line(" [dry-run] Would translate id_no={$idNo}: " . mb_substr($shortDescriptionEn, 0, 50) . '...');
$bar->advance();
continue;
}

// Call Google Translate API
$texts = $shortDescriptionEn === $descriptionEn
? [$shortDescriptionEn]
: [$shortDescriptionEn, $descriptionEn];
Expand Down Expand Up @@ -123,8 +171,9 @@ public function handle(): int
$bar->finish();
$this->newLine();

// Write translation results back to JSON as a backup
if (!$this->option('dry-run')) {
$outputDir = storage_path('app/private/unesco/normalized');
$outputDir = storage_path('app/private/unesco');
$outputPath = $outputDir . '/world_heritage_sites_translation.json';

if (!is_dir($outputDir)) {
Expand Down
9 changes: 6 additions & 3 deletions src/app/Console/Commands/WorldHeritageBuild.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ class WorldHeritageBuild extends Command
{--jp-missing-limit=200 : Max missing ids to print to console}

{--algolia : Also import records into Algolia}
{--algolia-truncate : Clear Algolia index before import}';
{--algolia-truncate : Clear Algolia index before import}

{--translate-jp-from-json : Use translation JSON for Japanese translation}';

protected $description = 'Rebuild local DB and import UNESCO World Heritage data (dump -> split -> import)';

Expand Down Expand Up @@ -105,8 +107,9 @@ public function handle(): int

if ((bool) $this->option('translate-jp')) {
$this->callOrFail('world-heritage:translate-short-description-japanese', array_filter([
'--force' => true,
'--dry-run' => (bool) $this->option('translate-jp-dry-run') ? true : null,
'--force' => true,
'--dry-run' => (bool) $this->option('translate-jp-dry-run') ? true : null,
'--from-json' => (bool) $this->option('translate-jp-from-json') ? true : null,
], static fn ($v) => $v !== null));
}

Expand Down
6 changes: 3 additions & 3 deletions src/app/Models/WorldHeritage.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\SoftDeletes;

class WorldHeritage extends Model
Expand Down Expand Up @@ -60,9 +60,9 @@ public function images(): HasMany
->orderBy('sort_order', 'asc');
}

public function descriptions(): HasMany
public function descriptions(): HasOne
{
return $this->hasMany(WorldHeritageDescription::class, 'world_heritage_site_id', 'id');
return $this->hasOne(WorldHeritageDescription::class, 'world_heritage_site_id', 'id');
}

protected function casts(): array
Expand Down
2 changes: 1 addition & 1 deletion src/app/Models/WorldHeritageDescription.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class WorldHeritageDescription extends Model
'updated_at',
];

public function worldHeritageSite(): BelongsTo
public function heritageSite(): BelongsTo
{
return $this->belongsTo(WorldHeritage::class, 'world_heritage_site_id', 'id');
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use App\Models\Country;
use App\Models\Image;
use App\Models\WorldHeritage;
use App\Models\WorldHeritageDescription;
use Database\Seeders\DatabaseSeeder;
use Illuminate\Support\Facades\DB;
use Tests\TestCase;
Expand Down Expand Up @@ -57,6 +58,7 @@ private function refresh(): void
Country::truncate();
DB::table('site_state_parties')->truncate();
Image::truncate();
WorldHeritageDescription::truncate();
DB::connection('mysql')->statement('SET FOREIGN_KEY_CHECKS=1;');
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use App\Models\Country;
use App\Models\WorldHeritage;
use App\Models\WorldHeritageDescription;
use App\Packages\Domains\Ports\Dto\HeritageSearchResult;
use App\Packages\Domains\Ports\WorldHeritageSearchPort;
use App\Packages\Domains\WorldHeritageQueryService;
Expand Down Expand Up @@ -48,6 +49,7 @@ private function refresh(): void
WorldHeritage::truncate();
Country::truncate();
Image::truncate();
WorldHeritageDescription::truncate();
DB::table('site_state_parties')->truncate();
DB::connection('mysql')->statement('SET FOREIGN_KEY_CHECKS=1;');
}
Expand All @@ -72,6 +74,7 @@ private function arrayData(): array
'latitude' => 0.0,
'longitude' => 0.0,
'short_description' => '氷期後のブナの自然拡散史を示すヨーロッパ各地の原生的ブナ林群から成る越境・連続資産。',
'short_description_jp' => 'あいうえお',
'unesco_site_url' => 'https://whc.unesco.org/en/list/1133',
'state_parties_codes' => [
'ALB','AUT','BEL','BIH','BGR','HRV','CZE','FRA','DEU','ITA','MKD','POL','ROU','SVK','SVN','ESP','CHE','UKR'
Expand Down Expand Up @@ -157,6 +160,7 @@ public function test_check_data_value(): void
$this->assertEquals($this->arrayData()['latitude'], $result->getLatitude());
$this->assertEquals($this->arrayData()['longitude'], $result->getLongitude());
$this->assertEquals($this->arrayData()['short_description'], $result->getShortDescription());
$this->assertEquals($this->arrayData()['short_description_jp'], $result->getShortDescriptionJp());
$this->assertEquals($this->arrayData()['unesco_site_url'], $result->getUnescoSiteUrl());
$this->assertEquals($expectedCodes, $result->getStatePartyCodes());
$this->assertEquals($orderedExpected, $result->getStatePartiesMeta());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Mockery;
use Tests\TestCase;
use Illuminate\Support\Collection;
use App\Models\WorldHeritageDescription;

final class WorldHeritageQueryService_searchHeritagesTest extends TestCase
{
Expand Down Expand Up @@ -81,6 +82,7 @@ private function refresh(): void
Country::truncate();
DB::table('site_state_parties')->truncate();
Image::truncate();
WorldHeritageDescription::truncate();
DB::connection('mysql')->statement('SET FOREIGN_KEY_CHECKS=1;');
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use App\Models\Country;
use App\Models\Image;
use App\Models\WorldHeritageDescription;
use App\Packages\Domains\WorldHeritageReadQueryService;
use App\Models\WorldHeritage;
use Database\Seeders\DatabaseSeeder;
Expand Down Expand Up @@ -39,6 +40,7 @@ private function refresh(): void
Country::truncate();
DB::table('site_state_parties')->truncate();
Image::truncate();
WorldHeritageDescription::truncate();
DB::connection('mysql')->statement('SET FOREIGN_KEY_CHECKS=1;');
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use App\Models\Country;
use App\Models\Image;
use App\Models\WorldHeritage;
use App\Models\WorldHeritageDescription;
use App\Packages\Domains\WorldHeritageEntityCollection;
use Database\Seeders\DatabaseSeeder;
use Illuminate\Support\Facades\DB;
Expand Down Expand Up @@ -34,6 +35,7 @@ private function refresh(): void
WorldHeritage::truncate();
Country::truncate();
Image::truncate();
WorldHeritageDescription::truncate();
DB::table('site_state_parties')->truncate();
DB::connection('mysql')->statement('SET FOREIGN_KEY_CHECKS=1;');
}
Expand Down Expand Up @@ -63,6 +65,7 @@ private function arraySingleData(): array
'latitude' => 34.6851,
'longitude' => 135.8048,
'short_description' => 'Temples and shrines of the first permanent capital of Japan.',
'short_description_jp' => 'あいうえお',
'image_url' => '',
'unesco_site_url' => 'https://whc.unesco.org/en/list/668/',
],
Expand All @@ -89,6 +92,7 @@ private function arrayMultiData(): array
'latitude' => 0.0,
'longitude' => 0.0,
'short_description' => 'Transnational serial property of European beech forests illustrating post-glacial expansion and ecological processes across Europe.',
'short_description_jp' => 'あいうえお',
'image_url' => '',
'unesco_site_url' => 'https://whc.unesco.org/en/list/1133/',
'state_parties' => [
Expand Down Expand Up @@ -132,6 +136,7 @@ private function arrayMultiData(): array
'latitude' => 0.0,
'longitude' => 0.0,
'short_description' => 'Transnational Silk Road corridor across China, Kazakhstan and Kyrgyzstan illustrating exchange of goods, ideas and beliefs.',
'short_description_jp' => 'あいうえお',
'image_url' => '',
'unesco_site_url' => 'https://whc.unesco.org/en/list/1442/',
'state_parties' => ['CHN','KAZ','KGZ'],
Expand Down Expand Up @@ -166,6 +171,7 @@ public function test_collection_check_type(): void
$data['area_hectares'],
$data['buffer_zone_hectares'],
$data['short_description'],
$data['short_description_jp'],
null,
$data['unesco_site_url'],
$data['state_parties'] ?? [],
Expand Down Expand Up @@ -205,6 +211,7 @@ public function test_collection_check_count_value(): void
$data['area_hectares'],
$data['buffer_zone_hectares'],
$data['short_description'],
$data['short_description_jp'],
null,
$data['unesco_site_url'],
$data['state_parties'] ?? [],
Expand Down Expand Up @@ -238,6 +245,7 @@ public function test_multi_collection_check_type(): void
$data['area_hectares'],
$data['buffer_zone_hectares'],
$data['short_description'],
$data['short_description_jp'],
null,
$data['unesco_site_url'],
$data['state_parties'] ?? [],
Expand Down Expand Up @@ -271,6 +279,7 @@ public function test_multi_collection_check_count_value(): void
$data['area_hectares'],
$data['buffer_zone_hectares'],
$data['short_description'],
$data['short_description_jp'],
null,
$data['unesco_site_url'],
$data['state_parties'] ?? [],
Expand Down
10 changes: 10 additions & 0 deletions src/app/Packages/Domains/Test/WorldHeritageEntityTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use App\Models\Country;
use App\Models\WorldHeritage;
use App\Models\WorldHeritageDescription;
use Illuminate\Support\Facades\DB;
use Tests\TestCase;
use App\Packages\Domains\WorldHeritageEntity;
Expand Down Expand Up @@ -31,6 +32,7 @@ private function refresh(): void
WorldHeritage::truncate();
Country::truncate();
DB::table('site_state_parties')->truncate();
WorldHeritageDescription::truncate();
DB::connection('mysql')->statement('SET FOREIGN_KEY_CHECKS=1;');
}
}
Expand All @@ -54,6 +56,7 @@ private function arraySingleData(): array
'latitude' => 34.6851,
'longitude' => 135.8048,
'short_description' => 'Temples and shrines of the first permanent capital of Japan.',
'short_description_jp' => 'これはテストです',
'image_url' => '',
'unesco_site_url' => 'https://whc.unesco.org/en/list/668/',
'state_parties' => null,
Expand Down Expand Up @@ -85,6 +88,7 @@ private function arrayMultiData(): array
'latitude' => 0.0,
'longitude' => 0.0,
'short_description' => 'Transnational serial property of European beech forests illustrating post-glacial expansion and ecological processes across Europe.',
'short_description_jp' => 'これはテストです',
'image_url' => '',
'unesco_site_url' => 'https://whc.unesco.org/en/list/1133/',
'state_parties' => [
Expand Down Expand Up @@ -133,6 +137,7 @@ public function test_entity_check_single_type(): void
$this->arraySingleData()['area_hectares'],
$this->arraySingleData()['buffer_zone_hectares'],
$this->arraySingleData()['short_description'],
$this->arraySingleData()['short_description_jp'],
null, // collection (ImageEntityCollection)
$this->arraySingleData()['unesco_site_url'],
$this->arraySingleData()['state_parties'] ?? [],
Expand Down Expand Up @@ -162,6 +167,7 @@ public function test_entity_check_single_value(): void
$this->arraySingleData()['area_hectares'],
$this->arraySingleData()['buffer_zone_hectares'],
$this->arraySingleData()['short_description'],
$this->arraySingleData()['short_description_jp'],
null,
$this->arraySingleData()['unesco_site_url'],
$this->arraySingleData()['state_parties'] ?: [],
Expand All @@ -183,6 +189,7 @@ public function test_entity_check_single_value(): void
$this->assertEquals($this->arraySingleData()['area_hectares'], $entity->getAreaHectares());
$this->assertEquals($this->arraySingleData()['buffer_zone_hectares'], $entity->getBufferZoneHectares());
$this->assertEquals($this->arraySingleData()['short_description'], $entity->getShortDescription());
$this->assertEquals($this->arraySingleData()['short_description_jp'], $entity->getShortDescriptionJp());
$this->assertEquals($this->arraySingleData()['unesco_site_url'], $entity->getUnescoSiteUrl());
$this->assertSame(['JPN'], $entity->getStatePartyCodes());
$this->assertSame($this->arraySingleData()['state_parties_meta'], $entity->getStatePartyMeta());
Expand All @@ -208,6 +215,7 @@ public function test_entity_check_multi_type(): void
$this->arrayMultiData()['area_hectares'],
$this->arrayMultiData()['buffer_zone_hectares'],
$this->arrayMultiData()['short_description'],
$this->arrayMultiData()['short_description_jp'],
null,
$this->arrayMultiData()['unesco_site_url'],
$this->arrayMultiData()['state_parties'] ?? [],
Expand Down Expand Up @@ -237,6 +245,7 @@ public function test_entity_check_multi_value(): void
$this->arrayMultiData()['area_hectares'],
$this->arrayMultiData()['buffer_zone_hectares'],
$this->arrayMultiData()['short_description'],
$this->arrayMultiData()['short_description_jp'],
null, // collection
$this->arrayMultiData()['unesco_site_url'],
$this->arrayMultiData()['state_parties'] ?? [],
Expand All @@ -257,6 +266,7 @@ public function test_entity_check_multi_value(): void
$this->assertEquals($this->arrayMultiData()['area_hectares'], $entity->getAreaHectares());
$this->assertEquals($this->arrayMultiData()['buffer_zone_hectares'], $entity->getBufferZoneHectares());
$this->assertEquals($this->arrayMultiData()['short_description'], $entity->getShortDescription());
$this->assertEquals($this->arrayMultiData()['short_description_jp'], $entity->getShortDescriptionJp());
$this->assertEquals($this->arrayMultiData()['unesco_site_url'], $entity->getUnescoSiteUrl());
$this->assertEquals($this->arrayMultiData()['state_parties'], $entity->getStatePartyCodes());
$this->assertEquals($this->arrayMultiData()['state_parties_meta'], $entity->getStatePartyMeta());
Expand Down
Loading
Loading