From 17472c2c2d2d53dc0b19b3921a2d1e5736a80ca7 Mon Sep 17 00:00:00 2001 From: pbarroca <pbarroca@afi-sa.fr> Date: Tue, 7 Feb 2017 12:26:29 +0100 Subject: [PATCH] dev #49440 add standard update in prepare integration phase --- VERSIONS_WIP/49440 | 1 + library/Class/Cosmogramme/Generator.php | 102 ++++++++++--- .../Cosmogramme/Generator/AbstractTask.php | 2 +- .../Integration/PhasePrepareIntegrations.php | 106 +++++++++----- .../Class/Cosmogramme/LandingDirectory.php | 15 ++ library/Class/IntBib.php | 32 +++++ .../PhasePrepareIntegrationsTest.php | 136 ++++++++++++++++++ 7 files changed, 342 insertions(+), 52 deletions(-) create mode 100644 VERSIONS_WIP/49440 diff --git a/VERSIONS_WIP/49440 b/VERSIONS_WIP/49440 new file mode 100644 index 00000000000..733b3354af2 --- /dev/null +++ b/VERSIONS_WIP/49440 @@ -0,0 +1 @@ + - ticket #49440 : Integration Nanook : Mise à jour de l'étalon à chaque import lorsque Nanook est le seul SIGB à importer. \ No newline at end of file diff --git a/library/Class/Cosmogramme/Generator.php b/library/Class/Cosmogramme/Generator.php index 60a220bebe0..306ec02d53d 100644 --- a/library/Class/Cosmogramme/Generator.php +++ b/library/Class/Cosmogramme/Generator.php @@ -23,12 +23,17 @@ class Class_Cosmogramme_Generator { use Trait_Translator, Trait_Loggable, Trait_TimeSource; - protected $_params = [], $_landing_directory; + protected + $_params = [], + $_landing_directory, + $_last_error = '', + $_update = false; public function generate($params) { $this->_params = $params; - $this->_landing_directory = Class_Cosmogramme_LandingDirectory::getInstance(); + + $this->_last_error = ''; if (!$this->isValid()) return false; @@ -45,13 +50,32 @@ class Class_Cosmogramme_Generator { } - protected function isValid() { - return $this->validateDirectory() && $this->validateProfiles(); + public function update($subdir) { + return $this->generate(['path_ftp' => $subdir, + 'type_sigb' => Class_IntBib::SIGB_NANOOK, + 'service_nanook' => Class_IntBib::findFirstBy([])->getUrlServer(), + 'creer_annexes' => Class_CodifAnnexe::count() ? '1' : '2']); + } + + + public function isValid() { + return $this->isUpdate() + ? null != $this->getUpdatableStandard() + : $this->validateDirectory() && $this->validateProfiles(); + } + + + public function getUpdatableStandard() { + if (null === Class_IntMajAuto::findFirstBy([]) + || !Class_IntBib::isSingleNanook()) + return null; + + return $this->getLandingDirectory()->getUpdatableStandard(); } protected function validateDirectory() { - return $this->_landing_directory->couldGenerateFrom($this->_params['path_ftp']); + return $this->getLandingDirectory()->couldGenerateFrom($this->_params['path_ftp']); } @@ -62,10 +86,10 @@ class Class_Cosmogramme_Generator { protected function getProfilesValidator() { - if (Class_IntBib::SIGB_NANOOK == $this->_params['type_sigb']) + if ($this->isNanook()) return new Class_Cosmogramme_GeneratorProfilesNanookValidator(); - if (Class_IntBib::SIGB_PERGAME == $this->_params['type_sigb']) + if ($this->isPergame()) return new Class_Cosmogramme_GeneratorProfilesPergameValidator(); return null; @@ -73,8 +97,8 @@ class Class_Cosmogramme_Generator { protected function _generateLibraries() { - if (!$libraries = $this->_landing_directory->getLibrariesOf($this->_params['path_ftp'])) { - $this->log($this->_('Étalon des bibliothèques vide')); + if (!$libraries = $this->getLandingDirectory()->getLibrariesOf($this->_params['path_ftp'])) { + $this->logError($this->_('Étalon des bibliothèques vide')); return false; } @@ -135,10 +159,10 @@ class Class_Cosmogramme_Generator { $bib = new Class_Cosmogramme_Generator_FixedIdBib(); $bib->updateAttributes(['id_site' => $elem[0], - 'libelle' => trim($elem[1]), - 'ville' => $this->_params['path_ftp'], - 'id_zone' => 1, - 'visibilite' => Class_Bib::V_DATA]) + 'libelle' => trim($elem[1]), + 'ville' => $this->_params['path_ftp'], + 'id_zone' => 1, + 'visibilite' => Class_Bib::V_DATA]) ->save(); Class_IntBib::deleteBy(['id_bib' => $bib->getIdSite()]); @@ -154,7 +178,7 @@ class Class_Cosmogramme_Generator { 'Max_par_carte' => '3', 'Max_par_document' => '3'])]); - if (Class_IntBib::SIGB_NANOOK == $this->_params['type_sigb']) + if ($this->isNanook()) $int_bib ->setCommSigb(Class_IntBib::COM_NANOOK) ->setCommParams(serialize(['url_serveur' => $this->_params['service_nanook']])); @@ -216,32 +240,36 @@ class Class_Cosmogramme_Generator { protected function getPlannedGenerator() { - return (Class_IntBib::SIGB_NANOOK == $this->_params['type_sigb']) + return $this->isNanook() ? new Class_Cosmogramme_GeneratorPlannedNanook() : new Class_Cosmogramme_GeneratorPlannedPergame(); } protected function _generateSections() { - $sections = $this->_landing_directory->getSectionsOf($this->_params['path_ftp']); + $sections = $this->getLandingDirectory()->getSectionsOf($this->_params['path_ftp']); return (new Class_Cosmogramme_Generator_SectionsTask($this))->run($sections); } protected function _generateLocations() { - $locations = $this->_landing_directory->getLocationsOf($this->_params['path_ftp']); + $locations = $this->getLandingDirectory()->getLocationsOf($this->_params['path_ftp']); return (new Class_Cosmogramme_Generator_LocationsTask($this))->run($locations); } protected function _generateKinds() { - $kinds = $this->_landing_directory->getKindsOf($this->_params['path_ftp']); + $kinds = $this->getLandingDirectory()->getKindsOf($this->_params['path_ftp']); return (new Class_Cosmogramme_Generator_KindsTask($this))->run($kinds); } protected function _generateDewey() { $this->logTitle($this->_('7 - Création des classes Dewey')); + if ($this->isUpdate()) { + $this->log($this->_('Ignoré en mode mise à jour')); + return true; + } Class_CodifDewey::deleteBy(['id_dewey' => range(0, 9)]); @@ -279,8 +307,44 @@ class Class_Cosmogramme_Generator { } + public function isUpdate() { + return $this->_update; + } + + + public function beUpdate() { + $this->_update = true; + return $this; + } + + + /** @category testing */ + public function setLandingDirectory($landing_directory) { + $this->_landing_directory = $landing_directory; + return $this; + } + + + protected function getLandingDirectory() { + return $this->_landing_directory + ? $this->_landing_directory + : Class_Cosmogramme_LandingDirectory::getInstance(); + } + + protected function logTitle($title) { - $this->log('<h3>' . $title . '</h3>'); + return $this->log('<h3>' . $title . '</h3>'); + } + + + protected function logError($message) { + $this->_last_error = $message; + return $this->log($message); + } + + + public function getLastError() { + return $this->_last_error; } diff --git a/library/Class/Cosmogramme/Generator/AbstractTask.php b/library/Class/Cosmogramme/Generator/AbstractTask.php index f3b2730a43a..04782c1d97c 100644 --- a/library/Class/Cosmogramme/Generator/AbstractTask.php +++ b/library/Class/Cosmogramme/Generator/AbstractTask.php @@ -36,7 +36,7 @@ abstract class Class_Cosmogramme_Generator_AbstractTask { return false; } - $this->logTitle($this->_('%d - Création des %s', $this->_id, $this->_name)); + $this->logTitle($this->_('%d - Création des %s', $this->_index, $this->_name)); $date = $this->getCurrentDate(); $datas = $this->_prepare($datas); diff --git a/library/Class/Cosmogramme/Integration/PhasePrepareIntegrations.php b/library/Class/Cosmogramme/Integration/PhasePrepareIntegrations.php index 71ebad6015d..e4aff4d4189 100644 --- a/library/Class/Cosmogramme/Integration/PhasePrepareIntegrations.php +++ b/library/Class/Cosmogramme/Integration/PhasePrepareIntegrations.php @@ -30,13 +30,12 @@ class Class_Cosmogramme_Integration_PhasePrepareIntegrations extends Class_Cosmo $_label = 'Préparation des intégrations'; - public function _init($phase) { if (!$this->_ftp_path = Class_CosmoVar::get('ftp_path')) - throw new Class_Cosmogramme_Integration_PhasePrepareIntegrationsException('La variable ftp_path n\'est pas définie'); + throw new Class_Cosmogramme_Integration_PhasePrepareIntegrationsException($this->_('La variable ftp_path n\'est pas définie')); if (!$this->_integration_path = Class_CosmoVar::get('integration_path')) - throw new Class_Cosmogramme_Integration_PhasePrepareIntegrationsException('La variable integration_path n\'est pas définie'); + throw new Class_Cosmogramme_Integration_PhasePrepareIntegrationsException($this->_('La variable integration_path n\'est pas définie')); } @@ -46,7 +45,9 @@ class Class_Cosmogramme_Integration_PhasePrepareIntegrations extends Class_Cosmo public function _execute() { - (new Class_Systeme_Report_Publication())->push($this->_log); + $this + ->_publishStatusReport() + ->_updateStandard(); $this->_log->ecrire('<h4>' . $this->_('Déplacement des intégrations en file d\'attente') . '</h4>'); $this->_log->ecrire('<br><table class="blank" cellspacing="0" cellpadding="5px">'); @@ -61,49 +62,83 @@ class Class_Cosmogramme_Integration_PhasePrepareIntegrations extends Class_Cosmo } + protected function _publishStatusReport() { + (new Class_Systeme_Report_Publication())->push($this->_log); + return $this; + } + + + protected function _updateStandard() { + $generator = (new Class_Cosmogramme_Generator())->beUpdate(); + if (!$standard_dir = $generator->getUpdatableStandard()) + return $this; + + $this->_log->ecrire('<h4>' . $this->_('Mise à jour de l\'étalon') . '</h4>'); + $generator->update($standard_dir) + ? $this->_log->addSuccess($this->_('OK')) + : $this->_log->addError($this->_('Erreur : %s', + $generator->getLastError())); + return $this; + } + + public function _runOne($majauto) { $id_bib = $majauto->getIdBib(); - if(!$bib = Class_IntBib::find($id_bib)) + if (!$bib = Class_IntBib::find($id_bib)) return; - $this->_log->ecrire( '<tr><td class="blank"><span class="bib">' . $bib->getNomCourt($id_bib) .'</span></td><td class="blank">'.$majauto->getNomFichier().'</td><td class="blank">'); + $this->_log + ->ecrire('<tr><td class="blank"><span class="bib">' . $bib->getNomCourt($id_bib) .'</span></td>' + .'<td class="blank">'.$majauto->getNomFichier().'</td><td class="blank">'); $ftpfile = $this->_getFtpFile($majauto->getNomFichier()); $id_upload = Class_CosmoVar::get('ID_upload') + 1; - $newfile = "integre$id_upload.pan"; - - if (false !== strpos($majauto->getNomFichier(), 'http://')) { - $uri = $majauto->getNomFichier(); - if (Class_Cosmogramme_Integration::findFirstBy(['traite' => 'non', - 'fichier' => $uri])) - return $this; - - $this->_log->ecrire('<span class="vert">Création de l\'intégration pour '. $uri .'</span></td>'); - $this->_newIntegration($uri, $majauto); - return $this; - } + $newfile = 'integre' . $id_upload . '.pan'; + if (false !== strpos($majauto->getNomFichier(), 'http://')) + return $this->_prepareUrl($majauto); if (!$ftpfile || !$this->getFileSystem()->is_file($ftpfile)) { - $this->_log->ecrire("pas de transfert pour: $ftpfile</td>"); + $this->_log->ecrire($this->_('pas de transfert pour : %s', $ftpfile) . '</td>'); return $this; } if (!$this->_checkFileSize($ftpfile, $majauto)) return $this; - if (true !== $this->getFilesystem()->rename($ftpfile, $this->_integration_path.$newfile)) { - $this->_log->ecrire('<span class="rouge">erreur au transfert du fichier</span></td>'); - $this->_incrementData('traitement_erreurs'); - return $this; + $filesystem = $this->getFilesystem(); + if (true !== $filesystem->rename($ftpfile, $this->_integration_path.$newfile)) { + $this->_log + ->ecrire(sprintf('<span class="rouge">%s</span></td>', + $this->_('erreur au transfert du fichier'))); + + $this->_incrementData('traitement_erreurs'); + return $this; } - $this->_log->ecrire('<span class="vert">transfert vers '.$newfile .'</span></td>'); + $this->_log + ->ecrire(sprintf('<span class="vert">%s</span></td>', + $this->_('transfert vers %s', $newfile))); + $this->_newIntegration($newfile, $majauto); Class_CosmoVar::setValueOf('ID_upload', $id_upload); } + protected function _prepareUrl($majauto) { + $uri = $majauto->getNomFichier(); + if (Class_Cosmogramme_Integration::findFirstBy(['traite' => 'non', + 'fichier' => $uri])) + return $this; + + $this->_log->ecrire(sprintf('<span class="vert">%s</span></td>', + $this->_('Création de l\'intégration pour %s', $uri))); + $this->_newIntegration($uri, $majauto); + + return $this; + } + + public function _getFtpFile($filename) { $ftp_path = $this->_ftp_path; if(strpos($filename, '[DATE]') === false) @@ -121,11 +156,14 @@ class Class_Cosmogramme_Integration_PhasePrepareIntegrations extends Class_Cosmo $pos++; $ftp_path .= substr($filename, 0, $pos); - $filename =substr($filename, $pos); + $filename = substr($filename, $pos); } if (!$dir = $this->getFileSystem()->opendir($ftp_path)) { - $this->_log->ecrire('<span class="rouge">répertoire inaccessible: '.$ftp_path.'</span>'); + $this->_log + ->ecrire(sprintf('<span class="rouge">%s</span>', + $this->_('répertoire inaccessible: %s', $ftp_path))); + $this->_incrementData('traitement_erreurs'); return null; } @@ -137,6 +175,7 @@ class Class_Cosmogramme_Integration_PhasePrepareIntegrations extends Class_Cosmo $ret = $ftp_path.$file; break; } + $this->getFileSystem()->closedir($dir); return $ret; } @@ -150,17 +189,20 @@ class Class_Cosmogramme_Integration_PhasePrepareIntegrations extends Class_Cosmo $minsize = $majauto->getTailleMinImportTotal(); $type_operation = $majauto->getTypeOperation(); - - if($minsize > 0 && $file_type == 0 && $type_operation == 2 ) { + if ($minsize > 0 && $file_type == 0 && $type_operation == 2) { $file_size = filesize($file); - if($file_size > 0) + if ($file_size > 0) $file_size = (int) (($file_size / 1024) / 1024); - if($file_size < $minsize) { - $this->_log->ecrire('<span class="rouge">Le fichier est trop petit : '.$file_size.' mo -> taille minimun attendue : '.$minsize.' mo</span></td>'); - return false; + if ($file_size < $minsize) { + $this->_log + ->ecrire(sprintf('<span class="rouge">%s</span></td>', + $this->_('Le fichier est trop petit : %s mo -> taille minimum attendue : %s mo', + $file_size, $minsize))); + return false; } } + return true; } diff --git a/library/Class/Cosmogramme/LandingDirectory.php b/library/Class/Cosmogramme/LandingDirectory.php index 798c55efee2..50c51c2a19c 100644 --- a/library/Class/Cosmogramme/LandingDirectory.php +++ b/library/Class/Cosmogramme/LandingDirectory.php @@ -77,6 +77,13 @@ class Class_Cosmogramme_LandingDirectory { } + public function getUpdatableStandard() { + if (($subdir = $this->getSingleSubdirectory()) + && $this->couldGenerateFrom($subdir)) + return $subdir; + } + + public function getSubdirPath($subdir) { return $this->_path . (DIRECTORY_SEPARATOR != substr($this->_path, -1) ? DIRECTORY_SEPARATOR : '') @@ -141,4 +148,12 @@ class Class_Cosmogramme_LandingDirectory { return $subdirs; } + + + public function getSingleSubdirectory() { + if (!$subdirs = $this->getSubdirectories()) + return null; + + return 1 == count($subdirs) ? current($subdirs) : null; + } } \ No newline at end of file diff --git a/library/Class/IntBib.php b/library/Class/IntBib.php index 941daaba7a7..2035dcd33be 100644 --- a/library/Class/IntBib.php +++ b/library/Class/IntBib.php @@ -46,6 +46,33 @@ class IntBibLoader extends Storm_Model_Loader { return $user_int_bib->findAllWithSameCommunication(); return new Storm_Collection(); } + + + public function isSingleNanook() { + if (1 == Class_IntBib::count() + && Class_IntBib::findFirstBy([])->isNanook()) + return true; + + $server = null; + foreach(Class_IntBib::findAll() as $library) + if (!$this->_isLibraryNanook($library, $server)) + return false; + + return true; + } + + + protected function _isLibraryNanook($library, &$server) { + if (!$library->isNanook()) + return false; + + if (null == $server) { + $server = $library->getUrlServer(); + return true; + } + + return $server == $library->getUrlServer(); + } } @@ -242,6 +269,11 @@ class Class_IntBib extends Storm_Model_Abstract { } + public function isNanook() { + return static::SIGB_NANOOK == $this->getSigb(); + } + + public function isDisconnected() { return static::COM_NONE == $this->getCommSigb() && static::SIGB_NONE == $this->getSigb(); diff --git a/tests/library/Class/Cosmogramme/Integration/PhasePrepareIntegrationsTest.php b/tests/library/Class/Cosmogramme/Integration/PhasePrepareIntegrationsTest.php index 07d6aa04f33..8d78c39b9bd 100644 --- a/tests/library/Class/Cosmogramme/Integration/PhasePrepareIntegrationsTest.php +++ b/tests/library/Class/Cosmogramme/Integration/PhasePrepareIntegrationsTest.php @@ -268,3 +268,139 @@ class PhasePrepareIntegrationsWithOAIIntegrationAlreadyRegisteredTest extends Ph $this->assertEquals(3, count(Class_Cosmogramme_Integration::findAll())); } } + + + +class PhasePrepareIntegrationsNanookStandardTest + extends Class_Cosmogramme_Integration_PhaseTestCase { + protected $_http_client; + + public function setUp() { + parent::setUp(); + + Zend_Registry::set('sql', $this->mock()->beStrict()); + + $file_system = $this->mock() + ->whenCalled('is_file') + ->with('ftp/my-library.net/transferts/foo/mylibrarytotal.txt') + ->answers(false) + + ->beStrict(); + + $this->_http_client = $this->mock() + ->whenCalled('postData') + ->answers(''); + + Class_AdminVar::set('STATUS_REPORT_PUSH_URL', ''); + + Class_Systeme_Report_Publication::setDefaultHttpClient($this->_http_client); + $this->fixture('Class_Profil', ['id' => 1, 'libelle' => 'My Bokeh']); + + Class_Cosmogramme_Integration_PhasePrepareIntegrations::setFileSystem($file_system); + Class_Cosmogramme_Integration_PhasePrepareIntegrations::setTimeSource(new TimeSourceForTest('2015-03-26 14:00:00')); + + $landing_directory = $this + ->mock() + ->whenCalled('getUpdatableStandard')->answers('foo') + + ->whenCalled('getLibrariesOf')->with('foo') + ->answers(['BIB_SPS_UTT|ID_SITE|LIBELLE', + '2|My library']) + + ->whenCalled('getSectionsOf')->with('foo') + ->answers(['BIB_C_SECTION|CODE|LIBELLE', + '4|Adultes']) + + ->whenCalled('getLocationsOf')->with('foo') + ->answers(['BIB_C_EMPLACEMENT|CODE|LIBELLE', + '9|Manga']) + + ->whenCalled('getKindsOf')->with('foo') + ->answers(['BIB_GENRES|SUPPORT|CODE|LIBELLE|DOC', + '0|1|Music|f']) + + ->beStrict(); + + Class_Cosmogramme_LandingDirectory::setInstance($landing_directory); + + $this->_phase = $this->_buildPhase('PrepareIntegrations')->run(); + } + + + public function tearDown() { + Class_Systeme_Report_Publication::resetHttpClient(); + parent::tearDown(); + } + + + protected function _prepareFixtures() { + $this->fixture('Class_CosmoVar', + ['id' => 'ID_upload', 'valeur' => 1178]); + + $this->fixture('Class_CosmoVar', + ['id' => 'integration_path', 'valeur' => 'ftp/my-library.net/integration/']); + + $this->fixture('Class_CosmoVar', + ['id' => 'ftp_path', 'valeur' => 'ftp/my-library.net/transferts/']); + + $this->fixture('Class_CosmoVar', + ['id' => 'integration_date', 'valeur' => '2015-03-23 12:00:00']); + + $this->fixture('Class_IntProfilDonnees', + ['id' => 102, + 'libelle' => 'Unimarc Pergame', + 'accents' => Class_IntProfilDonnees::ENCODING_WINDOWS_ANSI, + 'rejet_periodiques' => 1, + 'id_article_periodique' => Class_IntProfilDonnees::SERIAL_FORMAT_PERGAME, + 'type_fichier' => Class_IntProfilDonnees::FT_RECORDS, + 'format' => Class_IntProfilDonnees::FORMAT_UNIMARC, + 'attributs' => [] + ] + ); + + $this->fixture('Class_IntProfilDonnees', + ['id' => 103, + 'libelle' => 'OAI', + 'accents' => Class_IntProfilDonnees::ENCODING_WINDOWS_ANSI, + 'rejet_periodiques' => 1, + 'id_article_periodique' => Class_IntProfilDonnees::SERIAL_FORMAT_PERGAME, + 'type_fichier' => Class_IntProfilDonnees::FT_RECORDS, + 'format' => Class_IntProfilDonnees::FORMAT_UNIMARC_XML, + 'attributs' => [] + ] + ); + + $this->fixture('Class_IntBib', ['id' => 2, + 'nom_court' => 'My library', + 'sigb' => Class_IntBib::SIGB_NANOOK]); + + $this->fixture('Class_IntMajAuto', ['id' => 100, + 'id_prog' => 100, + 'id_bib' => 2, + 'libelle' => 'Notices - import total', + 'profil' => 102, + 'type_operation' => 2, + 'type_doc' => 0, + 'nom_fichier' => 'foo/mylibrarytotal.txt', + 'rang' => 100, + 'taille_min_import_total' => 0]); + } + + + protected function _getPreviousPhase() { + return (new Class_Cosmogramme_Integration_Phase(0)) + ->beCron(); + } + + + /** @test */ + public function logShouldContainsStandardUpdateOk() { + $this->assertContains('<h4>Mise à jour de l\'étalon</h4> OK', $this->_log_content); + } + + + /** @test */ + public function deweyShouldNotBeGenerated() { + $this->assertEquals(0, Class_CodifDewey::count()); + } +} \ No newline at end of file -- GitLab