diff --git a/app/Console/Commands/DumpUntranslatedAttributes.php b/app/Console/Commands/DumpUntranslatedAttributes.php new file mode 100644 index 000000000..065102381 --- /dev/null +++ b/app/Console/Commands/DumpUntranslatedAttributes.php @@ -0,0 +1,74 @@ + 'item.work_types', + 'technique' => 'item.techniques', + 'medium' => 'item.media', + 'object_type' => 'item.object_types', + 'topic' => 'item.topics', + ]; + + public function handle(): int + { + $attribute = $this->choice('Select attribute', array_keys($this->attributes)); + $locale = $this->choice('Select locale', config('translatable.locales')); + $prefix = $this->option('prefix'); + $output = $this->option('output'); + + $rows = $this->getUntranslatedAttributes($attribute, $locale, $prefix) + ->map(fn ($count, $value) => [$value, $count]); + + $header = [ + sprintf('%s (%s)', Str::ucfirst(trans("item.$attribute")), Str::upper($locale)), + 'Count', + ]; + + if ($output) { + $writer = Writer::createFromPath($output, 'w+'); + $writer->insertOne($header); + $writer->insertAll($rows); + + $this->info("Data has been exported to $output"); + } else { + $this->table($header, $rows); + } + + return self::SUCCESS; + } + + private function getUntranslatedAttributes(string $attribute, string $locale, ?string $prefix): LazyCollection + { + $translations = trans($this->attributes[$attribute], locale: $locale); + + return $this->getValuesWithCounts($attribute, $locale, $prefix) + ->reject(fn ($count, $value) => in_array($value, $translations)) + ->sortDesc(); + } + + private function getValuesWithCounts(string $attribute, string $locale, ?string $prefix): LazyCollection + { + return ItemTranslation::query() + ->select($attribute) + ->where('locale', $locale) + ->when($prefix, fn ($query) => $query->where('item_id', 'like', "$prefix%")) + ->lazy() + ->pluck($attribute) + ->flatMap(fn ($value) => str($value)->split('/\s*;\s*/')) + ->filter() + ->countBy(); + } +} \ No newline at end of file diff --git a/app/Enums/FrontendEnum.php b/app/Enums/FrontendEnum.php index e5e550622..1f92a3ece 100644 --- a/app/Enums/FrontendEnum.php +++ b/app/Enums/FrontendEnum.php @@ -6,4 +6,5 @@ enum FrontendEnum: string { case WEBUMENIA = 'webumenia'; case MORAVSKA_GALERIE = 'moravska-galerie'; + case UPM = 'upm'; } diff --git a/app/Filesystem/WebDAVAdapter.php b/app/Filesystem/WebDAVAdapter.php new file mode 100644 index 000000000..c0be9fd66 --- /dev/null +++ b/app/Filesystem/WebDAVAdapter.php @@ -0,0 +1,18 @@ +encodePath($path); + return parent::lastModified($path); + } +} \ No newline at end of file diff --git a/app/Helpers/general.php b/app/Helpers/general.php index 12e7ad3f3..8d5c6ea02 100644 --- a/app/Helpers/general.php +++ b/app/Helpers/general.php @@ -325,7 +325,7 @@ function convertEmptyStringsToNull($array) { } function formatName($name) { - return preg_replace('/^([^,]*),\s*(.*)$/', '$2 $1', $name); + return preg_replace('/^([^,–]*),\s*(.*)$/', '$2 $1', $name); } function starts_with_upper($str) { diff --git a/app/Import.php b/app/Import.php index b6c821708..e65ea7080 100644 --- a/app/Import.php +++ b/app/Import.php @@ -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); diff --git a/app/Importers/AbstractImporter.php b/app/Importers/AbstractImporter.php index b46230fa6..49a4def53 100644 --- a/app/Importers/AbstractImporter.php +++ b/app/Importers/AbstractImporter.php @@ -263,7 +263,7 @@ protected function getJp2Files( return $this->iipFilesMap[$import_record] ->filter( fn(SplFileInfo $file) => preg_match( - sprintf('#^%s\.jp2$#', $image_filename_format), + sprintf('#^%s\.jp[2f]$#', $image_filename_format), $file->getBasename() ) ) diff --git a/app/Importers/MmpImporter.php b/app/Importers/MmpImporter.php new file mode 100644 index 000000000..88ce653d0 --- /dev/null +++ b/app/Importers/MmpImporter.php @@ -0,0 +1,150 @@ + 'Inventární číslo', + 'title' => 'Titul', + 'dating' => 'Datace vzniku', + 'inscription' => 'Signatura', + ]; + + protected $defaults = [ + 'gallery:sk' => 'Múzeum Prahy, MMP', + 'gallery:cs' => 'Muzeum Prahy, MMP', + ]; + + private array $workTypeTranslationKeys; + private array $techniqueTranslationKeys; + private array $mediumTranslationKeys; + private array $topicTranslationKeys; + + protected function init(): void + { + $this->sanitizers[] = function ($value) { + return empty_to_null(trim($value)); + }; + + $this->workTypeTranslationKeys = array_flip(trans('item.work_types', locale: 'cs')); + $this->techniqueTranslationKeys = array_flip(trans('item.techniques', locale: 'cs')); + $this->mediumTranslationKeys = array_flip(trans('item.media', locale: 'cs')); + $this->topicTranslationKeys = array_flip(trans('item.topics', locale: 'cs')); + } + + protected function getItemId(array $record): string + { + return str($record['Inventární číslo']) + ->swap([ + ' ' => '_', + '/' => '-', + ]) + ->prepend('CZE:MP.'); + } + + protected function getItemImageFilenameFormat(array $record): string + { + return str($record['Inventární číslo']) + ->replace('/', '_') + ->append('(-.*)?'); + } + + protected function hydrateAuthor(array $record): string + { + if ($record['Autor'] === 'Anonym') { + return 'Neznámy autor'; + } + + return str($record['Autor']) + ->trim() + ->replaceMatches('/(.*?) /', '$1, ', 1); + } + + protected function hydrateWorkType(array $record, string $locale): ?string + { + $replacements = [ + 'malba' => 'malířství', + ]; + + return str($record['Výtvarný druh']) + ->split('/\s*;\s*/') + ->map(fn (string $workType) => $replacements[$workType] ?? $workType) + ->when($locale !== 'cs', fn ($workTypes) => $workTypes->map(function (string $workType) use ($locale) { + $key = $this->workTypeTranslationKeys[$workType] ?? null; + return $key ? trans("item.work_types.$key", locale: $locale) : null; + })) + ->filter() + ->join('; ') ?: null; + } + + protected function hydrateTechnique(array $record, string $locale): ?string + { + if ($locale === 'cs') { + return $record['Technika']; + } + + return str($record['Technika']) + ->split('/\s*;\s*/') + ->map(function (string $technique) use ($locale) { + $key = $this->techniqueTranslationKeys[$technique] ?? null; + return $key ? trans("item.techniques.$key", locale: $locale) : null; + }) + ->filter() + ->join('; ') ?: null; + } + + protected function hydrateMedium(array $record, string $locale): ?string + { + if ($locale === 'cs') { + return $record['Materiál']; + } + + return str($record['Materiál']) + ->split('/\s*;\s*/') + ->map(function (string $medium) use ($locale) { + $key = $this->mediumTranslationKeys[$medium] ?? null; + return $key ? trans("item.media.$key", locale: $locale) : null; + }) + ->filter() + ->join('; ') ?: null; + } + + protected function hydrateTopic(array $record, string $locale): ?string + { + if ($locale === 'cs') { + return $record['Námět/téma']; + } + + return str($record['Námět/téma']) + ->split('/\s*;\s*/') + ->map(function (string $topic) use ($locale) { + $key = $this->topicTranslationKeys[$topic] ?? null; + return $key ? trans("item.topics.$key", locale: $locale) : null; + }) + ->filter() + ->join('; ') ?: null; + } + + protected function hydrateMeasurement(array $record, $locale): ?string + { + if (empty($record['Rozměr'])) { + return null; + } + + $replacements = trans('item.measurement_replacements', [], $locale); + return strtr($record['Rozměr'], $replacements); + } + + protected function hydrateDateEarliest(array $record): int + { + return Date::createFromFormat('d.m.Y', $record['(n) Datace OD'])->year; + } + + protected function hydrateDateLatest(array $record): int + { + return Date::createFromFormat('d.m.Y', $record['(n) Datace DO'])->year; + } +} \ No newline at end of file diff --git a/app/Importers/UpmImporter.php b/app/Importers/UpmImporter.php new file mode 100644 index 000000000..590bb75b1 --- /dev/null +++ b/app/Importers/UpmImporter.php @@ -0,0 +1,227 @@ + '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', + '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", + ]; + + private array $workTypeTranslationKeys; + private array $techniqueTranslationKeys; + private array $mediumTranslationKeys; + private array $objectTypeTranslationKeys; + private array $topicTranslationKeys; + + + protected function init() + { + $this->sanitizers[] = function ($value) { + return empty_to_null(trim($value)); + }; + + $this->workTypeTranslationKeys = array_flip(trans('item.work_types', locale: 'cs')); + $this->techniqueTranslationKeys = array_flip(trans('item.techniques', locale: 'cs')); + $this->mediumTranslationKeys = array_flip(trans('item.media', locale: 'cs')); + $this->objectTypeTranslationKeys = array_flip(trans('item.object_types', locale: 'cs')); + $this->topicTranslationKeys = array_flip(trans('item.topics', locale: 'cs')); + } + + 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('/^(?[^–]*)(\s–\s(?.*))?$/', $author, $matches); + + if (!isset($matches['name'], $matches['role'])) { + return $author; + } + + return sprintf('%s – %s', formatName($matches['name']), $matches['role']); + }) + ->join('; '); + } + + protected function hydrateWorkType(array $record, string $locale): ?string + { + if ($locale === 'cs') { + return $record['Výtvarný druh']; + } + + return str($record['Výtvarný druh']) + ->split('/\s*;\s*/') + ->map(function (string $workType) use ($locale) { + $key = $this->workTypeTranslationKeys[$workType] ?? null; + return $key ? trans("item.work_types.$key", locale: $locale) : null; + }) + ->filter() + ->join('; ') ?: null; + } + + protected function hydrateTechnique(array $record, string $locale): ?string + { + if ($locale === 'cs') { + return $record['Technika']; + } + + return str($record['Technika']) + ->split('/\s*;\s*/') + ->map(function (string $technique) use ($locale) { + $key = $this->techniqueTranslationKeys[$technique] ?? null; + return $key ? trans("item.techniques.$key", locale: $locale) : null; + }) + ->filter() + ->join('; ') ?: null; + } + + protected function hydrateMedium(array $record, string $locale): ?string + { + if ($locale === 'cs') { + return $record['Materiál']; + } + + return str($record['Materiál']) + ->split('/\s*;\s*/') + ->map(function (string $medium) use ($locale) { + $key = $this->mediumTranslationKeys[$medium] ?? null; + return $key ? trans("item.media.$key", locale: $locale) : null; + }) + ->filter() + ->join('; ') ?: null; + } + + protected function hydrateObjectType(array $record, string $locale): ?string + { + if ($locale === 'cs') { + return $record['Typ']; + } + + return str($record['Typ']) + ->split('/\s*;\s*/') + ->map(function (string $objectType) use ($locale) { + $key = $this->objectTypeTranslationKeys[$objectType] ?? null; + return $key ? trans("item.object_types.$key", locale: $locale) : null; + }) + ->filter() + ->join('; ') ?: null; + } + + protected function hydrateTopic(array $record, string $locale): ?string + { + if ($locale === 'cs') { + return $record['Námět']; + } + + return str($record['Námět']) + ->split('/\s*;\s*/') + ->map(function (string $topic) use ($locale) { + $key = $this->topicTranslationKeys[$topic] ?? null; + return $key ? trans("item.topics.$key", locale: $locale) : null; + }) + ->filter() + ->join('; ') ?: null; + } + + 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); + } +} \ No newline at end of file diff --git a/app/Item.php b/app/Item.php index b77eb6231..1865fd875 100644 --- a/app/Item.php +++ b/app/Item.php @@ -108,6 +108,7 @@ class Item extends Model implements IndexableModel, TranslatableContract 'exhibition', 'box', 'location', + 'object_type', ]; public static $rules = array( diff --git a/app/Matchers/AuthorityMatcher.php b/app/Matchers/AuthorityMatcher.php index 58e5e5b68..10b0215b1 100644 --- a/app/Matchers/AuthorityMatcher.php +++ b/app/Matchers/AuthorityMatcher.php @@ -97,14 +97,14 @@ protected function findByFullname($fullname) public static function parse($author) { - if (!preg_match('/^((?.*?)\s*(?\(.*\))?(?\s+-\s+.*)?,\s+)?(?.*?)\s*(?\(.*\)|\/.*)?$/', $author, $matches)) { + if (!preg_match('/^((?.*?)\s*(?\(.*\))?(?\s+[-–]\s+.*)?,\s+)?(?.*?)\s*(?\(.*\)|\/.*)?$/', $author, $matches)) { return null; } return [ 'surname' => $matches['surname'] ?: null, 'alt_surname' => trim($matches['alt_surname'], '()') ?: null, - 'role' => ltrim($matches['role'], ' -') ?: null, + 'role' => ltrim($matches['role'], ' -–') ?: null, 'name' => $matches['name'] ?: null, 'alt_name' => trim($matches['alt_name'] ?? '', '()/') ?: null, ]; diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 243d63348..e58cfe713 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -1,5 +1,6 @@ string('title', 512)->change(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('item_translations', function (Blueprint $table) { + $table->string('title')->change(); + }); + } +}; diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 78b93ca72..037ceb127 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -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); } diff --git a/database/seeders/ImportsTableSeeder.php b/database/seeders/ImportsTableSeeder.php new file mode 100644 index 000000000..f0bbc26c0 --- /dev/null +++ b/database/seeders/ImportsTableSeeder.php @@ -0,0 +1,21 @@ + 'UPM', + 'dir_path' => 'UPM', + 'iip_dir_path' => 'UPM', + 'class_name' => UpmImporter::class, + 'disk' => 'import_iip', + ]); + } +} \ No newline at end of file diff --git a/lang/cs/item.php b/lang/cs/item.php index 22b433810..34df452d5 100644 --- a/lang/cs/item.php +++ b/lang/cs/item.php @@ -108,36 +108,39 @@ ], ], 'measurement_replacements' => [ - 'a' => 'výška hlavní části', - 'a.' => 'výška hlavní části', - 'b' => 'výška vedlejší části', - 'b.' => 'výška vedlejší části', - 'čas' => 'čas', - 'd' => 'délka', - 'd.' => 'délka', - 'h' => 'hloubka/tloušťka', - 'h.' => 'hloubka/tloušťka', - 'hmot' => 'hmotnost', - 'hmot.' => 'hmotnost', - 'hr' => 'hloubka s rámem', - 'jiný' => 'jiný nespecifikovaný', - 'p' => 'průměr/ráže', - 'p.' => 'průměr/ráže', - 'r.' => 'ráže', - 'ryz' => 'ryzost', - 's' => 'šířka', - 's.' => 'šířka', - 'sd.' => 'šířka grafické desky', - 'sp' => 'šířka s paspartou', - 'sp.' => 'šířka s paspartou', - 'sr' => 'šířka s rámem', - 'v' => 'celková výška/délka', - 'v.' => 'celková výška/délka', - 'vd.' => 'výška grafické desky', - 'vp' => 'výška s paspartou', - 'vp.' => 'výška s paspartou', - 'vr' => 'výška s rámem', - '=' => ' ', + 'a=' => 'výška hlavní části ', + 'a.=' => 'výška hlavní části ', + 'b=' => 'výška vedlejší části ', + 'b.=' => 'výška vedlejší části ', + 'čas=' => 'čas ', + 'd=' => 'délka ', + 'd.=' => 'délka ', + 'h=' => 'hloubka/tloušťka ', + 'h.=' => 'hloubka/tloušťka ', + 'hmot=' => 'hmotnost ', + 'hmot.=' => 'hmotnost ', + 'hr=' => 'hloubka s rámem ', + 'jiný=' => 'jiný nespecifikovaný ', + 'p=' => 'průměr/ráže ', + 'p.=' => 'průměr/ráže ', + 'r.=' => 'ráže ', + 'ryz=' => 'ryzost ', + 's=' => 'šířka ', + 's.=' => 'šířka ', + 'sd.=' => 'šířka grafické desky ', + 'sp=' => 'šířka s paspartou ', + 'sp.=' => 'šířka s paspartou ', + 'sr=' => 'šířka s rámem ', + 'v=' => 'celková výška/délka ', + 'v.=' => 'celková výška/délka ', + 'vd.=' => 'výška grafické desky ', + 'vp=' => 'výška s paspartou ', + 'vp.=' => 'výška s paspartou ', + 'vr=' => 'výška s rámem ', + 'rv.=' => 'výška s rámem ', + 'rš.=' => 'šířka s rámem ', + 'v-cm=' => 'výška ', + 'š-cm=' => 'šířka ', ], 'untitled' => 'bez názvu', 'authority_roles' => [ @@ -295,8 +298,12 @@ 'zväčšovanie' => 'zvětšování', 'čiernobiela fotografia' => 'černobílá fotografie', ], + 'object_types' => [ + 'kniha' => 'kniha', + ], 'topics' => [ 'figurálna kompozícia' => 'figurální kompozice', + 'ornament' => 'ornament', ], 'state_editions' => [ 'autorizovaný pozitív' => 'autorizovaný pozitiv', diff --git a/lang/en/item.php b/lang/en/item.php index 486ab7b7a..90369c0c6 100644 --- a/lang/en/item.php +++ b/lang/en/item.php @@ -105,36 +105,39 @@ ], ], 'measurement_replacements' => [ - 'a' => 'height of the main part', - 'a.' => 'height of the main part', - 'b' => 'height of the secondary part', - 'b.' => 'height of the secondary part', - 'čas' => 'time', - 'd' => 'length', - 'd.' => 'length', - 'h' => 'depth/thickness', - 'h.' => 'depth/thickness', - 'hmot' => 'mass', - 'hmot.' => 'mass', - 'hr' => 'depth with frame', - 'jiný' => 'other, unspecified', - 'p' => 'diameter, calibre/gauge', - 'p.' => 'diameter, calibre/gauge', - 'r.' => 'calibre/gauge', - 'ryz' => 'purity', - 's' => 'width', - 's.' => 'width', - 'sd.' => 'width of the printing plate', - 'sp' => 'width with mount', - 'sp.' => 'width with mount', - 'sr' => 'width with frame', - 'v' => 'overall height/length', - 'v.' => 'overall height/length', - 'vd.' => 'height of the printing plate', - 'vp' => 'height with mount', - 'vp.' => 'height with mount', - 'vr' => 'height with frame', - '=' => ' ', + 'a=' => 'height of the main part ', + 'a.=' => 'height of the main part ', + 'b=' => 'height of the secondary part ', + 'b.=' => 'height of the secondary part ', + 'čas=' => 'time ', + 'd=' => 'length ', + 'd.=' => 'length ', + 'h=' => 'depth/thickness ', + 'h.=' => 'depth/thickness ', + 'hmot=' => 'mass ', + 'hmot.=' => 'mass ', + 'hr=' => 'depth with frame ', + 'jiný=' => 'other, unspecified ', + 'p=' => 'diameter, calibre/gauge ', + 'p.=' => 'diameter, calibre/gauge ', + 'r.=' => 'calibre/gauge ', + 'ryz=' => 'purity ', + 's=' => 'width ', + 's.=' => 'width ', + 'sd.=' => 'width of the printing plate ', + 'sp=' => 'width with mount ', + 'sp.=' => 'width with mount ', + 'sr=' => 'width with frame ', + 'v=' => 'overall height/length ', + 'v.=' => 'overall height/length ', + 'vd.=' => 'height of the printing plate ', + 'vp=' => 'height with mount ', + 'vp.=' => 'height with mount ', + 'vr=' => 'height with frame ', + 'rv.=' => 'height with frame ', + 'rš.=' => 'width with frame ', + 'v-cm=' => 'height ', + 'š-cm=' => 'width ', ], 'untitled' => 'untitled', 'authority_roles' => [ @@ -292,8 +295,12 @@ 'zväčšovanie' => 'enlarging', 'čiernobiela fotografia' => 'black-and-white photograph', ], + 'object_types' => [ + 'kniha' => 'book', + ], 'topics' => [ 'figurálna kompozícia' => 'figurative composition', + 'ornament' => 'ornament', ], 'state_editions' => [ 'autorizovaný pozitív' => 'authorized photographic print', diff --git a/lang/sk/item.php b/lang/sk/item.php index f15b18ba6..c755e2b3e 100644 --- a/lang/sk/item.php +++ b/lang/sk/item.php @@ -105,36 +105,39 @@ ], ], 'measurement_replacements' => [ - 'a' => 'výška hlavnej časti', - 'a.' => 'výška hlavnej časti', - 'b' => 'výška vedľajšej časti', - 'b.' => 'výška vedľajšej časti', - 'čas' => 'čas', - 'd' => 'dĺžka', - 'd.' => 'dĺžka', - 'h' => 'hĺbka/hrúbka', - 'h.' => 'hĺbka/hrúbka', - 'hmot' => 'hmotnosť', - 'hmot.' => 'hmotnosť', - 'hr' => 'hĺbka s rámom', - 'jiný' => 'nešpecifikované', - 'p' => 'priemer', - 'p.' => 'priemer', - 'r.' => 'ráž', - 'ryz' => 'rýdzosť', - 's' => 'šírka', - 's.' => 'šírka', - 'sd.' => 'šírka grafickej plochy', - 'sp' => 'šírka s paspartou', - 'sp.' => 'šírka s paspartou', - 'sr' => 'šírka s rámom', - 'v' => 'celková výška/dĺžka', - 'v.' => 'celková výška/dĺžka', - 'vd.' => 'výška grafickej dosky', - 'vp' => 'výška s paspartou', - 'vp.' => 'výška s paspartou', - 'vr' => 'výška s rámom', - '=' => ' ', + 'a=' => 'výška hlavnej časti ', + 'a.=' => 'výška hlavnej časti ', + 'b=' => 'výška vedľajšej časti ', + 'b.=' => 'výška vedľajšej časti ', + 'čas=' => 'čas ', + 'd=' => 'dĺžka ', + 'd.=' => 'dĺžka ', + 'h=' => 'hĺbka/hrúbka ', + 'h.=' => 'hĺbka/hrúbka ', + 'hmot=' => 'hmotnosť ', + 'hmot.=' => 'hmotnosť ', + 'hr=' => 'hĺbka s rámom' , + 'jiný=' => 'nešpecifikované ', + 'p=' => 'priemer ', + 'p.=' => 'priemer ', + 'r.=' => 'ráž ', + 'ryz=' => 'rýdzosť ', + 's=' => 'šírka ', + 's.=' => 'šírka ', + 'sd.=' => 'šírka grafickej plochy ', + 'sp=' => 'šírka s paspartou ', + 'sp.=' => 'šírka s paspartou ', + 'sr=' => 'šírka s rámom ', + 'v=' => 'celková výška/dĺžka ', + 'v.=' => 'celková výška/dĺžka ', + 'vd.=' => 'výška grafickej dosky ', + 'vp=' => 'výška s paspartou ', + 'vp.=' => 'výška s paspartou ', + 'vr=' => 'výška s rámom ', + 'rv.=' => 'výška s rámom ', + 'rš.=' => 'šírka s rámom ', + 'v-cm=' => 'výška ', + 'š-cm=' => 'šírka ', ], 'untitled' => 'bez názvu', 'authority_roles' => [ @@ -292,8 +295,12 @@ 'zväčšovanie' => 'zväčšovanie', 'čiernobiela fotografia' => 'čiernobiela fotografia', ], + 'object_types' => [ + 'kniha' => 'kniha', + ], 'topics' => [ 'figurálna kompozícia' => 'figurálna kompozícia', + 'ornament' => 'ornament', ], 'state_editions' => [ 'autorizovaný pozitív' => 'autorizovaný pozitív', diff --git a/tests/Importers/GmuRnlImporterTest.php b/tests/Importers/GmuRnlImporterTest.php index 35861ea86..083f703da 100644 --- a/tests/Importers/GmuRnlImporterTest.php +++ b/tests/Importers/GmuRnlImporterTest.php @@ -9,10 +9,11 @@ use Illuminate\Contracts\Translation\Translator; use Illuminate\Foundation\Testing\RefreshDatabase; use Tests\TestCase; +use Tests\WithoutSearchIndexing; class GmuRnlImporterTest extends TestCase { - use RefreshDatabase; + use RefreshDatabase, WithoutSearchIndexing; public function testImport() { diff --git a/tests/Importers/MmpImporterTest.php b/tests/Importers/MmpImporterTest.php new file mode 100644 index 000000000..8f7fa329e --- /dev/null +++ b/tests/Importers/MmpImporterTest.php @@ -0,0 +1,96 @@ +repositoryMock = $this->createMock(CsvRepository::class); + $this->importer = new MmpImporter( + app(AuthorityMatcher::class), + $this->repositoryMock, + app(Translator::class) + ); + } + + public function testImport() + { + $this->importData(); + + $item = Item::find('CZE:MP.H_014_487'); + + $this->assertEquals('H 014 487', $item->identifier); + $this->assertEquals('Beisch, Josef Antonín', $item->author); + $this->assertEquals(1701, $item->date_earliest); + $this->assertEquals(1800, $item->date_latest); + $this->assertEquals('Panna Marie Karlovská', $item->title); + $this->assertEquals('počátek 18.stol.', $item->dating); + $this->assertEquals('maliarstvo', $item->translate('sk')->work_type); + $this->assertEquals('malířství', $item->translate('cs')->work_type); + $this->assertEquals('painting', $item->translate('en')->work_type); + $this->assertEquals('olej', $item->translate('sk')->technique); + $this->assertEquals('olej', $item->translate('cs')->technique); + $this->assertEquals('oil', $item->translate('en')->technique); + $this->assertEquals('drevo', $item->translate('sk')->medium); + $this->assertEquals('dřevo', $item->translate('cs')->medium); + $this->assertEquals('wood', $item->translate('en')->medium); + $this->assertEquals(null, $item->translate('sk')->topic); + $this->assertEquals('obraz náboženský', $item->translate('cs')->topic); + $this->assertEquals(null, $item->translate('en')->topic); + $this->assertEquals('výška s rámom 31cm; šírka s rámom 21,5cm; výška 24,5cm; šírka 14,5cm', $item->translate('sk')->measurement); + $this->assertEquals('výška s rámem 31cm; šířka s rámem 21,5cm; výška 24,5cm; šířka 14,5cm', $item->translate('cs')->measurement); + $this->assertEquals('height with frame 31cm; width with frame 21,5cm; height 24,5cm; width 14,5cm', $item->translate('en')->measurement); + } + + 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 + [ + "Řada" => "H", + "Inventární číslo" => "H 014 487", + "Titul" => "Panna Marie Karlovská", + "Autor" => "Beisch Josef Antonín", + "Datace vzniku" => "počátek 18.stol.", + "(n) Datace OD" => "1.1.1701", + "(n) Datace DO" => "31.12.1800", + "Výtvarný druh" => "malba", + "Materiál" => "dřevo", + "Technika" => "olej", + "Rozměr" => "rv.=31cm; rš.=21,5cm; v-cm=24,5cm; š-cm=14,5cm", + "Námět/téma" => "obraz náboženský", + "Signatura" => "", + ]; + } +} \ No newline at end of file diff --git a/tests/Importers/OglImporterTest.php b/tests/Importers/OglImporterTest.php index e56e11158..b13e0ec4a 100644 --- a/tests/Importers/OglImporterTest.php +++ b/tests/Importers/OglImporterTest.php @@ -9,10 +9,11 @@ use Illuminate\Contracts\Translation\Translator; use Illuminate\Foundation\Testing\RefreshDatabase; use Tests\TestCase; +use Tests\WithoutSearchIndexing; class OglImporterTest extends TestCase { - use RefreshDatabase; + use RefreshDatabase, WithoutSearchIndexing; public function testId() { diff --git a/tests/Importers/PnpImporterTest.php b/tests/Importers/PnpImporterTest.php index 816785936..97f178172 100644 --- a/tests/Importers/PnpImporterTest.php +++ b/tests/Importers/PnpImporterTest.php @@ -9,10 +9,11 @@ use Illuminate\Contracts\Translation\Translator; use Illuminate\Foundation\Testing\RefreshDatabase; use Tests\TestCase; +use Tests\WithoutSearchIndexing; class PnpImporterTest extends TestCase { - use RefreshDatabase; + use RefreshDatabase, WithoutSearchIndexing; public function testId() { diff --git a/tests/Importers/PnpKarasekImporterTest.php b/tests/Importers/PnpKarasekImporterTest.php index 4dbc43bfc..25aa98542 100644 --- a/tests/Importers/PnpKarasekImporterTest.php +++ b/tests/Importers/PnpKarasekImporterTest.php @@ -9,10 +9,11 @@ use Illuminate\Contracts\Translation\Translator; use Illuminate\Foundation\Testing\RefreshDatabase; use Tests\TestCase; +use Tests\WithoutSearchIndexing; class PnpKarasekImporterTest extends TestCase { - use RefreshDatabase; + use RefreshDatabase, WithoutSearchIndexing; public function testId() { diff --git a/tests/Importers/UpmImporterTest.php b/tests/Importers/UpmImporterTest.php new file mode 100644 index 000000000..358a904ac --- /dev/null +++ b/tests/Importers/UpmImporterTest.php @@ -0,0 +1,123 @@ +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('Jiří Rathouský – grafická úprava, design vazby a přebalu', $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 16,5cm (konvice čajová s víčkem větší); celková výška/dĺžka 13,5-14cm (konvice čajová s víčkem menší)', $item->translate('sk')->measurement); + $this->assertEquals('celková výška/délka 16,5cm (konvice čajová s víčkem větší); celková výška/délka 13,5-14cm (konvice čajová s víčkem menší)', $item->translate('cs')->measurement); + $this->assertEquals('overall height/length 16,5cm (konvice čajová s víčkem větší); overall height/length 13,5-14cm (konvice čajová s víčkem menší)', $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('úžitkové umenie; grafický dizajn', $item->translate('sk')->work_type); + $this->assertEquals('užité umění;grafický design', $item->translate('cs')->work_type); + $this->assertEquals('applied arts; graphic design', $item->translate('en')->work_type); + $this->assertEquals('kresba', $item->translate('sk')->technique); + $this->assertEquals('kresba', $item->translate('cs')->technique); + $this->assertEquals('drawing', $item->translate('en')->technique); + $this->assertEquals('kniha', $item->translate('sk')->object_type); + $this->assertEquals('kniha', $item->translate('cs')->object_type); + $this->assertEquals('book', $item->translate('en')->object_type); + $this->assertEquals('papier', $item->translate('sk')->medium); + $this->assertEquals('papír', $item->translate('cs')->medium); + $this->assertEquals('paper', $item->translate('en')->medium); + $this->assertEquals('ornament', $item->translate('sk')->topic); + $this->assertEquals('ornament', $item->translate('cs')->topic); + $this->assertEquals('ornament', $item->translate('en')->topic); + $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" => "Rathouský, Jiří – grafická úprava, design vazby a přebalu", + "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" => "papír", + "Technika" => "kresba", + "Rozměry" => "v=16,5cm (konvice čajová s víčkem větší); v=13,5-14cm (konvice čajová s víčkem menší)", + "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", + ]; + } +} \ No newline at end of file diff --git a/tests/Matchers/AuthorityMatcherTest.php b/tests/Matchers/AuthorityMatcherTest.php index 3af7844f1..1490a9db6 100644 --- a/tests/Matchers/AuthorityMatcherTest.php +++ b/tests/Matchers/AuthorityMatcherTest.php @@ -7,10 +7,11 @@ use App\Matchers\AuthorityMatcher; use Illuminate\Foundation\Testing\RefreshDatabase; use Tests\TestCase; +use Tests\WithoutSearchIndexing; class AuthorityMatcherTest extends TestCase { - use RefreshDatabase; + use RefreshDatabase, WithoutSearchIndexing; public function testMatchAll() {