Skip to content

Commit

Permalink
[import] Add UPM importer
Browse files Browse the repository at this point in the history
  • Loading branch information
rastislav-chynoransky committed Dec 13, 2024
1 parent 9851bdd commit 4cac465
Show file tree
Hide file tree
Showing 6 changed files with 288 additions and 0 deletions.
1 change: 1 addition & 0 deletions app/Enums/FrontendEnum.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ enum FrontendEnum: string
{
case WEBUMENIA = 'webumenia';
case MORAVSKA_GALERIE = 'moravska-galerie';
case UPM = 'upm';
}
8 changes: 8 additions & 0 deletions app/Import.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ class Import extends Model
'completed_at' => 'datetime',
];

protected $fillable = [
'name',
'dir_path',
'iip_dir_path',
'class_name',
'disk',
];

public function user()
{
return $this->belongsTo(User::class);
Expand Down
144 changes: 144 additions & 0 deletions app/Importers/UpmImporter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
<?php

namespace App\Importers;

use App\Enums\FrontendEnum;

class UpmImporter extends AbstractImporter
{
protected $mapping = [
'identifier' => 'Inventárníčíslo',
'title:cs' => 'Název',
'title:sk' => 'Název',
'title:en' => 'Název EN',
'dating:cs' => 'Datace',
'dating:sk' => 'Datace',
'date_earliest' => 'Od',
'date_latest' => 'Do',
'work_type:cs' => 'Výtvarný druh',
'work_type:sk' => 'Výtvarný druh',
'object_type:cs' => 'Typ',
'object_type:sk' => 'Typ',
'medium:cs' => 'Materiál',
'medium:sk' => 'Materiál',
'technique:cs' => 'Technika',
'technique:sk' => 'Technika',
'topic:cs' => 'Námět',
'topic:sk' => 'Námět',
'inscription:cs' => 'Značení',
'inscription:sk' => 'Značení',
'related_work:sk' => 'Sbírka',
'related_work:cs' => 'Sbírka',
'acquisition_date' => 'Datum akvizice',
];

protected $defaults = [
'relationship_type:sk' => 'zo súboru',
'relationship_type:cs' => 'ze souboru',
'relationship_type:en' => 'collection',
'gallery:cs' => 'Uměleckoprůmyslové museum v Praze, UPM',
'gallery:sk' => 'Umeleckopriemyselné múzeum v Prahe, UPM',
'frontends' => [
FrontendEnum::UPM,
FrontendEnum::WEBUMENIA,
],
];

protected static $options = [
'delimiter' => ';',
'enclosure' => '"',
'escape' => '\\',
'newline' => "\n",
];

protected function init()
{
$this->sanitizers[] = function ($value) {
return empty_to_null(trim($value));
};
}

protected function getItemId(array $record)
{
return 'CZE:UPM.' . str($record['ID'])
->explode('_')
->transform(fn ($part) => str($part)
->replaceMatches('/\W/', '-')
->trim('-')
)
->join('_');
}

protected function getItemImageFilenameFormat(array $record): string
{
return str($record['ID'])
->explode('_')
->transform(fn ($part) => '0*' . preg_quote($part))
->join('_') . '(_.*)?';
}

protected function hydrateAuthor(array $record): string
{
$authors = str($record['Autor']);
if ($authors->isEmpty()) {
return 'Neznámý autor';
}

return $authors
->split('/\s*;\s*/')
->map(function (string $author) {
preg_match('/^(?<name>[^–]*)(\s–\s(?<role>.*))?$/', $author, $matches);

if (!isset($matches['name'], $matches['role'])) {
return $author;
}

return sprintf('%s (%s)', formatName($matches['name']), $matches['role']);
})
->join('; ');
}

protected function hydratePlace(array $record, string $locale): ?string
{
if (!in_array($locale, ['cs', 'sk'])) {
return null;
}

$place = str($record['Vznik'])->match('/^([^;]+)/');
return $place->isNotEmpty() ? $place->toString() : null;
}

protected function hydrateAdditionals(array $record, string $locale): ?array
{
if ($locale !== 'cs') {
return null;
}

$additionals = [];

if ($record['Způsob akvizice'] !== null) {
$additionals['acquisition'] = $record['Způsob akvizice'];
}

if ($record['Výstava'] !== null) {
$additionals['exhibition'] = $record['Výstava'];
}

$producer = str($record['Vznik'])->match('/;(.+)/');
if ($producer->isNotEmpty()) {
$additionals['producer'] = $producer->toString();
}

return $additionals ?: null;
}

protected function hydrateMeasurement(array $record, $locale): ?string
{
if (empty($record['Rozměry'])) {
return null;
}

$replacements = trans('item.measurement_replacements', [], $locale);
return strtr($record['Rozměry'], $replacements);
}
}
1 change: 1 addition & 0 deletions database/seeders/DatabaseSeeder.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public function run()
$this->call(CollectionsTableSeeder::class);
$this->call(CategoriesTableSeeder::class);
$this->call(ArticlesTableSeeder::class);
$this->call(ImportsTableSeeder::class);

// $this->call(SketchbooksTableSeeder::class);
}
Expand Down
21 changes: 21 additions & 0 deletions database/seeders/ImportsTableSeeder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace Database\Seeders;

use App\Import;
use App\Importers\UpmImporter;
use Illuminate\Database\Seeder;

class ImportsTableSeeder extends Seeder
{
public function run()
{
Import::create([
'name' => 'UPM',
'dir_path' => 'UPM',
'iip_dir_path' => 'UPM',
'class_name' => UpmImporter::class,
'disk' => 'import_iip',
]);
}
}
113 changes: 113 additions & 0 deletions tests/Importers/UpmImporterTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
<?php

namespace Tests\Importers;

use App\Import;
use App\Importers\UpmImporter;
use App\ImportRecord;
use App\Item;
use App\Matchers\AuthorityMatcher;
use App\Repositories\CsvRepository;
use Illuminate\Contracts\Translation\Translator;
use Illuminate\Foundation\Testing\RefreshDatabase;
use PHPUnit\Framework\MockObject\MockObject;
use Tests\TestCase;
use Tests\WithoutSearchIndexing;

class UpmImporterTest extends TestCase
{
use RefreshDatabase, WithoutSearchIndexing;

use WithoutSearchIndexing;

protected CsvRepository|MockObject $repositoryMock;

protected UpmImporter $importer;

public function setUp(): void
{
parent::setUp();
$this->repositoryMock = $this->createMock(CsvRepository::class);
$this->importer = new UpmImporter(
app(AuthorityMatcher::class),
$this->repositoryMock,
app(Translator::class)
);
}

public function testImport()
{
$this->importData();

$item = Item::find('CZE:UPM.GK_11090');

$this->assertEquals('GK 11090/E', $item->identifier);
$this->assertEquals('Luboš Kopáč (návrh vazby)', $item->author);
$this->assertEquals(1928, $item->date_earliest);
$this->assertEquals(1928, $item->date_latest);
$this->assertEquals('1986', $item->acquisition_date);
$this->assertEquals('Vazba knihy', $item->translate('sk')->title);
$this->assertEquals('Vazba knihy', $item->translate('cs')->title);
$this->assertEquals('Binding design', $item->translate('en')->title);
$this->assertEquals('celková výška/dĺžka 19,2cm; šírka 12cm', $item->translate('sk')->measurement);
$this->assertEquals('celková výška/délka 19,2cm; šířka 12cm', $item->translate('cs')->measurement);
$this->assertEquals('overall height/length 19,2cm; width 12cm', $item->translate('en')->measurement);
$this->assertEquals('zo súboru', $item->translate('sk')->relationship_type);
$this->assertEquals('ze souboru', $item->translate('cs')->relationship_type);
$this->assertEquals('collection', $item->translate('en')->relationship_type);
$this->assertEquals('Sbírka užité grafiky', $item->translate('cs')->related_work);
$this->assertEquals('užité umění;grafický design', $item->translate('cs')->work_type); // todo translate
$this->assertEquals('celokožená vazba, zlacení', $item->translate('cs')->technique); // todo translate
$this->assertEquals('kniha', $item->translate('cs')->object_type); // todo translate
$this->assertEquals('kůže;papír', $item->translate('cs')->medium); // todo translate
$this->assertEquals('ornament', $item->translate('cs')->topic); // todo translate
$this->assertEquals('1928', $item->translate('cs')->dating);
$this->assertEquals('Praha', $item->translate('cs')->place);
$this->assertEquals('Rösller', $item->translate('cs')->inscription);
$this->assertEquals('VŠUP atelier V.H.Brunnera (vazba)', $item->translate('cs')->additionals['producer']);
$this->assertEquals('převod', $item->translate('cs')->additionals['acquisition']);
$this->assertEquals('Japonsko design, 2019-2020', $item->translate('cs')->additionals['exhibition']);
}

private function importData(array $data = []): ImportRecord
{
$data = $this->fakeData($data);

$this->repositoryMock->method('getFiltered')->willReturn(new \ArrayIterator([$data]));

$importRecord = ImportRecord::factory()
->for(Import::factory())
->create();
$this->importer->import($importRecord, stream: null);
return $importRecord;
}

private function fakeData(array $overrides = []): array
{
return $overrides + [
"Inventárníčíslo" => "GK 11090/E",
"ID" => "GK_11090",
"Název" => "Vazba knihy",
"Název EN" => "Binding design",
"Autor" => "Kopáč, Luboš – návrh vazby",
"Vznik" => "Praha;VŠUP atelier V.H.Brunnera (vazba)",
"Datace" => "1928",
"Od" => "1928",
"Do" => "1928",
"Výtvarný druh" => "užité umění;grafický design",
"Typ" => "kniha",
"Materiál" => "kůže;papír",
"Technika" => "celokožená vazba, zlacení",
"Rozměry" => "v=19,2cm; s=12cm",
"Námět" => "ornament",
"tagy" => "",
"Značení" => "Rösller",
"Způsob akvizice" => "převod",
"Datum akvizice" => "1986",
"Výstava" => "Japonsko design, 2019-2020",
"Publikovat" => "Y",
"Sbírka" => "Sbírka užité grafiky",
"" => "Kolbersb",
];
}
}

0 comments on commit 4cac465

Please sign in to comment.