From a2b617104070bbe300019c504f5fb4286c324d05 Mon Sep 17 00:00:00 2001 From: efalcy <efalcy@afi-sa.fr> Date: Tue, 18 Feb 2020 17:53:18 +0100 Subject: [PATCH] dev#102219 : script migration Ressource numerique Ussel --- VERSIONS_WIP/102219 | 1 + library/Class/AlbumRessource.php | 11 + library/Class/UploadMover/Abstract.php | 24 ++- library/Class/UploadMover/HttpPost.php | 15 +- library/Class/UploadMover/LocalFile.php | 14 +- scripts/import_ussel.php | 256 ++++++++++++++++++++++++ 6 files changed, 295 insertions(+), 26 deletions(-) create mode 100644 VERSIONS_WIP/102219 create mode 100644 scripts/import_ussel.php diff --git a/VERSIONS_WIP/102219 b/VERSIONS_WIP/102219 new file mode 100644 index 00000000000..4b833839e89 --- /dev/null +++ b/VERSIONS_WIP/102219 @@ -0,0 +1 @@ + - ticket #102219 : Ussel : Reprise des données albums cartes postales \ No newline at end of file diff --git a/library/Class/AlbumRessource.php b/library/Class/AlbumRessource.php index a616f3ac7fa..11c9656976b 100644 --- a/library/Class/AlbumRessource.php +++ b/library/Class/AlbumRessource.php @@ -451,6 +451,17 @@ class Class_AlbumRessource extends Storm_Model_Abstract { } + /** + * @param $name string input file name + * @param $mover Class_UploadMover_Abstract + * @return Class_AlbumRessource + */ + public function setUploadMover($name, $mover) { + $this->getUploadHandler($name)->setUploadMover($mover); + return $this; + } + + /** * @return Class_Folder_Manager */ diff --git a/library/Class/UploadMover/Abstract.php b/library/Class/UploadMover/Abstract.php index 6ab0b63dd76..48a70e2f3fc 100644 --- a/library/Class/UploadMover/Abstract.php +++ b/library/Class/UploadMover/Abstract.php @@ -16,10 +16,12 @@ * * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE * along with BOKEH; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ abstract class Class_UploadMover_Abstract { + use Trait_Translator; + /** @var string */ protected $_error; @@ -30,7 +32,23 @@ abstract class Class_UploadMover_Abstract { * @param string $destination * @return bool */ - abstract public function moveTo($source, $destination); + public function moveTo($source, $destination) { + if ($this->_realMoveTo($source, $destination)) + return true; + + $this->setError($this->_('Impossible d\'écrire le fichier sur le serveur au chemin [%s]', + $destination)); + return false; + } + + + /** + * @codeCoverageIgnore + * @param string $source + * @param string $destination + * @return bool + */ + abstract protected function _realMoveTo($source, $destination); /** @@ -52,5 +70,3 @@ abstract class Class_UploadMover_Abstract { return $this->_error; } } - -?> \ No newline at end of file diff --git a/library/Class/UploadMover/HttpPost.php b/library/Class/UploadMover/HttpPost.php index 37798ac9c50..644935f106d 100644 --- a/library/Class/UploadMover/HttpPost.php +++ b/library/Class/UploadMover/HttpPost.php @@ -20,22 +20,15 @@ */ class Class_UploadMover_HttpPost extends Class_UploadMover_Abstract { - use Trait_Translator, - Trait_StaticFileWriter; + use Trait_StaticFileWriter; + /** * @codeCoverageIgnore * @param string $source * @param string $destination * @return bool */ - public function moveTo($source, $destination) { - if (!$this->getFileWriter()->moveUploadedFile($source, $destination)) { - $this->setError(sprintf($this->_('Impossible d\'écrire le fichier sur le serveur au chemin [%s]'), $destination)); - return false; - } - - return true; + protected function _realMoveTo($source, $destination) { + return $this->getFileWriter()->moveUploadedFile($source, $destination); } } - -?> \ No newline at end of file diff --git a/library/Class/UploadMover/LocalFile.php b/library/Class/UploadMover/LocalFile.php index f238097f297..90622211141 100644 --- a/library/Class/UploadMover/LocalFile.php +++ b/library/Class/UploadMover/LocalFile.php @@ -16,26 +16,18 @@ * * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE * along with BOKEH; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ class Class_UploadMover_LocalFile extends Class_UploadMover_Abstract { - use Trait_Translator; /** * @codeCoverageIgnore * @param string $source * @param string $destination * @return bool */ - public function moveTo($source, $destination) { + protected function _realMoveTo($source, $destination) { @rename($source, $destination); - if (!file_exists($destination)) { - $this->setError(sprintf($this->_('Impossible d\'écrire le fichier sur le serveur au chemin [%s]'), $destination)); - return false; - } - - return true; + return file_exists($destination); } } - -?> \ No newline at end of file diff --git a/scripts/import_ussel.php b/scripts/import_ussel.php new file mode 100644 index 00000000000..737e5046d84 --- /dev/null +++ b/scripts/import_ussel.php @@ -0,0 +1,256 @@ +<?php +error_reporting(E_ALL^E_DEPRECATED); +ini_set('display_startup_errors', 1); +ini_set('display_errors', 1); + +require __DIR__ . '/../console.php'; + +mkdir('/tmp/ussel'); + + +class UsselAlbumReportItem extends Class_Entity { + public static function newWith($record, $attributes = []) { + $ils_id = $record->get_subfield('001'); + return new static(array_merge(['BokehId' => $record->getId(), + 'IlsId' => $ils_id ? $ils_id[0] : 'n/a'], + $attributes)); + } + + + public static function description() { + return (new Class_TableDescription('ussel')) + ->addColumn('Bokeh id', 'bokeh_id') + ->addColumn('ILS id', 'ils_id') + ; + } +} + + + +class UsselAlbumImporter { + use Trait_MemoryCleaner; + + protected + $_base_path = '/home/webmaster/stl/php/bokeh/SAV_HCC', + $_base_category, + $_frbr_type, + $_handled, + $_no_links, + $_file_not_exists, + $_no_files, + $_all_files, + $_view; + + public function __construct() { + symlink($this->_base_path.'/La Courtine', $this->_base_path.'/LaCourtine'); + symlink($this->_base_path.'/Meymac/Mey656 .jpg', $this->_base_path.'/Meymac/Mey656.jpg'); + symlink($this->_base_path.'/Meymac/MEY658 .JPG', $this->_base_path.'/Meymac/MEY658.jpg'); + $this->_view = new ZendAfi_Controller_Action_Helper_View(); + $command = new Class_Testing_Command(); + $command->exec('find "'.$this->_base_path.'"'); + $this->_all_files = implode("\n", $command->getOutput()); + if (!trim($this->_all_files)) { + echo 'no files'; + exit; + } + } + + + public function run() { + $this->_handled = 0; + $this->_no_links = []; + $this->_file_not_exists = []; + $this->_no_files = []; + + if ( !$this->_base_category = Class_AlbumCategorie::getOrCreateRootCategory('Cartes Postales')) { + echo 'Base category not found'; + return; + } + + if (!$this->_frbr_type = Class_FRBR_LinkType::find(1)) { + echo 'FRBR link type not found'; + return; + } + + $page = 0; + while($records = Class_Notice::findAllBy(['type_doc' => 7, + 'order' => 'id_notice', + 'limitPage' => [$page, 100]])) { + $this->_runPage($records); + $this->_cleanMemory(); + $page++; + } + + return $this; + } + + + protected function _runPage($records) { + foreach($records as $record) + $this->_importRecord($record); + } + + + public function runPageTest() { + foreach (Class_Notice::findAllBy(['type_doc' => 7, + 'order' => 'id_notice', + 'limitPage' => [0, 5000]]) as $record) { + $existing_files = $this->_existingFilesOf($record); + } + } + + + public function report() { + echo implode("\n", + ['', '', + $this->_handled . ' notices traitées', + count($this->_no_links) . ' notices sans zones de liens', + count($this->_file_not_exists) . ' liens sans fichier correspondant', + count($this->_no_files) . ' notices sans aucun fichier correspondant', + '', '']); + + $this->_reportFile('ussel_no_links', + UsselAlbumReportItem::description(), + $this->_no_links); + + $this->_reportFile('ussel_file_not_exists', + UsselAlbumReportItem::description()->addColumn('Path', 'path'), + $this->_file_not_exists); + + $this->_reportFile('ussel_no_files', + UsselAlbumReportItem::description(), + $this->_no_files); + } + + + protected function _reportFile($name, $description, $data) { + file_put_contents($name . '.csv', + $this->_view->renderCsv($description, $data)); + } + + + protected function _importRecord($record) { + $this->_handled++; + echo '.'; + + $existing_files = $this->_existingFilesOf($record); + if ($existing_files->isEmpty()) { + $this->_no_files[] = UsselAlbumReportItem::newWith($record); + return; + } + + $album = Class_Album::newInstance(['categorie' => $this->_categoryFor($existing_files->first()), + 'titre' => $record->getTitrePrincipal(), + 'visible' => false, + 'description' => $record->getResume(), + 'matiere' => $this->_matersOf($record)]); + $album->beValidated()->save(); + + $this->_linkRecordToAlbum($record, $album); + + foreach($existing_files as $file) + $this->_addResourceTo($file, $album); + } + + + protected function _addResourceTo($file, $album) { + $ressource = Class_AlbumRessource::newInstance(['album' => $album, + 'titre' => '', + 'description' => '']); + + $ressource->save(); + $pathinfo = pathinfo($file); + $filename = $pathinfo['basename']; + $tmp_name = '/tmp/ussel/'.$filename; + + copy($file, $tmp_name); + $_FILES['fichier'] = ['size' => filesize($file), + 'name' => $filename, + 'tmp_name' => $tmp_name]; + + $ressource->setUploadMover('fichier', new Class_UploadMover_LocalFile); + if ($ressource->receiveFiles()) + return; + + echo $ressource->getErrors()['fichier']; + $ressource->delete(); + } + + + protected function _linkRecordToAlbum($record, $album) { + $source = Class_Url::absolute((new Class_Notice_Permalink())->paramsFor($record), null, true); + $target = Class_Url::absolute(array_merge(['id' => $album->getId()], + $album->getPermalink()), null, true); + + return Class_FRBR_Link::newInstance(['source' => $source, + 'target' => $target, + 'type' => $this->_frbr_type]) + ->save(); + } + + + protected function _categoryFor($path) { + $path = str_replace($this->_base_path, '', $path); + if (!$parts = array_filter(explode('/', pathinfo($path)['dirname']))) + return $this->_base_category; + + $parent = $this->_base_category; + foreach($parts as $part) + $parent = $this->_ensureSubCategory($parent, $part); + + return $parent; + } + + + protected function _ensureSubCategory($parent, $label) { + $attributes = ['parent_id' => $parent->getId(), 'libelle' => $label]; + if (!$category = Class_AlbumCategorie::findFirstBy($attributes)) { + $category = Class_AlbumCategorie::newInstance($attributes); + $category->save(); + } + + return $category; + } + + + protected function _matersOf($record) { + return implode(';', Class_Notice_Facette::facetsValuesFromRecordFilteredBy($record, 'isMatter')); + } + + + protected function _existingFilesOf($record) { + if (!$links = $record->get_subfield('856', 'u')) { + $this->_no_links[] = UsselAlbumReportItem::newWith($record); + return new Storm_Collection([]); + } + + return (new Storm_Collection($links)) + ->collect(function($each) { return $this->_base_path . $each; }) + ->collect(function($each) use($record) + { + if ($path = $this->_fileExists($each)) + return $path; + + $path = str_replace($this->_base_path, '', $each); + $this->_file_not_exists[] = UsselAlbumReportItem::newWith($record, + ['Path' => $path]); + return null; + }) + ->select(function($each) { return $each; }); + } + + + protected function _fileExists($path) { + if (file_exists($path)) + return $path; + + $matches = []; + if (preg_match('|^' . preg_quote($path) . '$|im', $this->_all_files, $matches)) + return $matches[0]; + } +} + + +(new UsselAlbumImporter) + ->run() + ->report(); -- GitLab