Skip to content

Commit

Permalink
Montée en version 2.2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
ebugat committed Mar 26, 2024
1 parent 1c3a303 commit 6e03e1a
Show file tree
Hide file tree
Showing 22 changed files with 335 additions and 179 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
</parent>
<groupId>fr.progilone.numahop</groupId>
<artifactId>numahop</artifactId>
<version>2.1.1</version>
<version>2.2.0</version>
<packaging>war</packaging>
<name>NumaHOP</name>
<description>NumaHOP</description>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ public class DigitalLibraryConfiguration extends AbstractDomainObject {
@Column(name = "mail")
private String mail;

/**
* envoi des fichiers en SFTP
*/
@Column(name = "sftp")
private boolean sftp;

/* Types de fichiers à exporter */
@Column(name = "export_view")
private boolean exportView;
Expand Down Expand Up @@ -239,6 +245,14 @@ public void setDefaultValue(final String defaultValue) {
this.defaultValue = defaultValue;
}

public boolean isSftp() {
return sftp;
}

public void setSftp(final boolean sftp) {
this.sftp = sftp;
}

@Override
public String toString() {
return "DigitalLibraryConfiguration{" + "label='"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package fr.progilone.pgcn.repository.document.conditionreport;

import fr.progilone.pgcn.domain.document.conditionreport.DescriptionProperty;
import fr.progilone.pgcn.domain.document.conditionreport.DescriptionValue;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
Expand All @@ -9,6 +10,8 @@ public interface DescriptionValueRepository extends JpaRepository<DescriptionVal

List<DescriptionValue> findByPropertyIdentifier(String propertyId);

List<DescriptionValue> findByProperty(DescriptionProperty property);

@Modifying
void deleteByPropertyIdentifier(String propertyId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,30 +38,6 @@ Page<DocUnitWorkflow> findDocUnitProgressStats(List<String> libraries,
LocalDate toDate,
Pageable pageable);

/**
* Recherche paginée
*
* @param libraries
* @param projects
* @param pgcnId
* @param states
* @param users
* @param fromDate
* @param toDate
* @return
*/
List<DocUnitWorkflow> findDocUnitProgressStatsPending(List<String> libraries,
List<String> projects,
boolean projetActive,
List<String> lots,
List<String> trains,
String pgcnId,
List<WorkflowStateKey> states,
final List<WorkflowStateStatus> status,
List<String> users,
LocalDate fromDate,
LocalDate toDate);

/**
* Recherche de DocUnitWorkflow
*
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -788,15 +788,6 @@ public boolean isDocumentReadyForArchivage(final String identifier) {
return doc.getExportData() != null && !doc.getExportData().getProperties().isEmpty();
}

/**
* Permet de s'assurer que les données d'export vers Omeka sont déjà existantes
*/
@Transactional(readOnly = true)
public boolean isDocumentReadyForDiffusionOmeka(final String identifier) {
final DocUnit doc = docUnitRepository.findById(identifier).orElseThrow();
return doc.getOmekaCollection() != null && doc.getOmekaItem() != null;
}

@Transactional(readOnly = true)
public Page<String> getDistinctTypes(final String search, final Integer page, final Integer size) {
if (StringUtils.isEmpty(search)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package fr.progilone.pgcn.service.document.conditionreport;

import fr.progilone.pgcn.domain.document.conditionreport.DescriptionProperty;
import fr.progilone.pgcn.domain.document.conditionreport.DescriptionValue;
import fr.progilone.pgcn.exception.PgcnValidationException;
import fr.progilone.pgcn.exception.message.PgcnError;
Expand Down Expand Up @@ -30,6 +31,11 @@ public List<DescriptionValue> findAll() {
return descriptionValueRepository.findAll();
}

@Transactional(readOnly = true)
public List<DescriptionValue> findByProperty(final DescriptionProperty property) {
return descriptionValueRepository.findByProperty(property);
}

@Transactional(readOnly = true)
public List<DescriptionValue> findByPropertyIdentifier(final String propertyId) {
return descriptionValueRepository.findByPropertyIdentifier(propertyId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ protected List<Object> convertCondReport(final CSVRecord record,
} else {
// get the allowed values
DescriptionProperty descProp = descriptionPropertyService.findByIdentifier(property);
List<DescriptionValue> allowedValues = descriptionValueService.findByPropertyIdentifier(descProp.getIdentifier());
List<DescriptionValue> allowedValues = descriptionValueService.findByProperty(descProp);
// if empty list, value is free to this property
if (!allowedValues.isEmpty()) { // value have to be in the allowedValues
Optional<DescriptionValue> findedVal = allowedValues.stream().filter(val -> StringUtils.equalsIgnoreCase(val.getLabel(), recordValue)).findFirst();
Expand All @@ -234,11 +234,11 @@ protected List<Object> convertCondReport(final CSVRecord record,
desc.setValue(findedVal.get());
condReportValues.add(desc);
LOG.warn("Propriété {} mappée", descProp.getLabel());
} else {
} else if (!checkAndWriteComments(descProp, recordValue, condReportValues)) {
LOG.warn("Propriété {} non mappée", descProp.getLabel());
errors.add(builder.reinit().setCode(PgcnErrorCode.CONDREPORT_DETAIL_DESC_NO_VALUE_FOR_PROP).setField("pgcnId").build());
}
} else {
} else if (!checkAndWriteComments(descProp, recordValue, condReportValues)) {
LOG.warn("Pas de valeurs associées à la propriété {}", descProp.getLabel());
errors.add(builder.reinit().setCode(PgcnErrorCode.CONDREPORT_DETAIL_DESC_BAD_VALUE).setField("pgcnId").build());
}
Expand All @@ -253,6 +253,31 @@ protected List<Object> convertCondReport(final CSVRecord record,
return condReportValues;
}

/**
* Check if comments are authorized, if so add it to the description
*
* @param descProp
* @param recordValue
* @param condReportValues
* @return true if comments were added, false otherwise
*/
protected boolean checkAndWriteComments(DescriptionProperty descProp, String recordValue, List<Object> condReportValues) {
final Optional<PropertyConfiguration> confOpt = descProp.getConfigurations()
.stream()
.filter(c -> c.getDescProperty() != null && StringUtils.equals(c.getDescProperty().getIdentifier(),
descProp.getIdentifier()))
.findAny();
if (confOpt.isPresent() && confOpt.get().isAllowComment() || descProp.isAllowComment()) {
Description desc = new Description();
desc.setProperty(descProp);
desc.setComment(recordValue);
condReportValues.add(desc);
LOG.warn("Commentaire {} mappé", descProp.getLabel());
return true;
}
return false;
}

/**
* create metadata values on the doc unit
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package fr.progilone.pgcn.service.exchange.digitallibrary;

import fr.progilone.pgcn.domain.administration.SftpConfiguration;
import fr.progilone.pgcn.domain.administration.digitallibrary.DigitalLibraryConfiguration;
import fr.progilone.pgcn.domain.administration.viewsformat.ViewsFormatConfiguration;
import fr.progilone.pgcn.domain.document.DocPropertyType;
Expand All @@ -19,11 +20,13 @@
import fr.progilone.pgcn.service.document.ui.UIBibliographicRecordService;
import fr.progilone.pgcn.service.exchange.cines.ExportMetsService;
import fr.progilone.pgcn.service.exchange.csv.ExportCSVService;
import fr.progilone.pgcn.service.exchange.ssh.SftpService;
import fr.progilone.pgcn.service.library.LibraryService;
import fr.progilone.pgcn.service.storage.AltoService;
import fr.progilone.pgcn.service.storage.BinaryStorageManager;
import fr.progilone.pgcn.service.util.CryptoService;
import fr.progilone.pgcn.service.util.DateUtils;
import fr.progilone.pgcn.service.util.ImageUtils;
import fr.progilone.pgcn.service.workflow.WorkflowService;
import jakarta.persistence.EntityNotFoundException;
import java.io.File;
Expand All @@ -44,6 +47,7 @@
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.slf4j.Logger;
Expand Down Expand Up @@ -86,6 +90,8 @@ public class DigitalLibraryDiffusionService {
private final AltoService altoService;
private final LibraryService libraryService;

private final SftpService sftpService;

public DigitalLibraryDiffusionService(final DocUnitService docUnitService,
final DigitalLibraryConfigurationService digitalLibraryConfigurationService,
final WorkflowService workflowService,
Expand All @@ -97,7 +103,8 @@ public DigitalLibraryDiffusionService(final DocUnitService docUnitService,
final ExportCSVService exportCSVService,
final MailService mailService,
final AltoService altoService,
final LibraryService libraryService) {
final LibraryService libraryService,
final SftpService sftpService) {
this.docUnitService = docUnitService;
this.digitalLibraryConfigurationService = digitalLibraryConfigurationService;
this.workflowService = workflowService;
Expand All @@ -110,6 +117,7 @@ public DigitalLibraryDiffusionService(final DocUnitService docUnitService,
this.mailService = mailService;
this.altoService = altoService;
this.libraryService = libraryService;
this.sftpService = sftpService;
}

@Transactional(readOnly = true)
Expand Down Expand Up @@ -167,32 +175,19 @@ public boolean exportDocToDigitalLibrary(final DocUnit du, final boolean multipl
return exported;
}

final File csv;
// Génération des fichiers / répertoires MEDIA
csv = exportDocUnit(doc, metaDC, mediasDir, conf, multiple, firstDoc);
final Pair<File, Path> result = exportDocUnit(doc, metaDC, mediasDir, conf, multiple, firstDoc);
final File csv = result.getKey();
final Path depotPath = result.getValue();

// Tranferts du csv et dossier media
if (mediasDir.toFile().exists() && csv.exists()) {

final FTPClient ftpClient = new FTPClient();

ftpClient.connect(conf.getAddress(), Integer.parseInt(conf.getPort()));

final boolean success = ftpClient.login(conf.getLogin(), cryptoService.decrypt(conf.getPassword()));

if (!success) {
LOG.error("Erreur de connexion ftp lors de l'export sur la Bibliothèque numérique");
exported = false;
// Envoi des documents en SFTP
if (conf.isSftp() && depotPath.toFile().exists()) {
exported = exportSftp(conf, multiple, lastDoc, csv.toPath(), depotPath);
} else {
ftpClient.changeWorkingDirectory(conf.getDeliveryFolder());
if (!multiple || lastDoc) {
putPathRecursively(csv, ftpClient);
}
LOG.info("Envoi du document {}", mediasDir.getFileName());
putPathRecursively(mediasDir.toFile(), ftpClient);
exported = true;
ftpClient.logout();
ftpClient.disconnect();
exported = exportFtp(conf, multiple, lastDoc, csv, mediasDir);
}
}

Expand Down Expand Up @@ -221,12 +216,64 @@ public boolean exportDocToDigitalLibrary(final DocUnit du, final boolean multipl
}

@Transactional
public File exportDocUnit(final DocUnit docUnit,
final BibliographicRecordDcDTO metaDc,
final Path mediaDir,
final DigitalLibraryConfiguration conf,
final boolean multiple,
final boolean firstDoc) throws IOException, PgcnTechnicalException {
public boolean exportSftp(final DigitalLibraryConfiguration conf, final boolean multiple, final boolean lastDoc, final Path csvPath, final Path mediasDirPath) {
final SftpConfiguration sftpConf = new SftpConfiguration();
sftpConf.setActive(true);
sftpConf.setHost(conf.getAddress());
sftpConf.setPort(Integer.valueOf(conf.getPort()));
sftpConf.setUsername(conf.getLogin());
sftpConf.setPassword(conf.getPassword());
try {
if (!multiple || lastDoc) {
String rootFolder = conf.getDeliveryFolder();
sftpConf.setTargetDir(rootFolder);
sftpService.sftpPut(sftpConf, csvPath);
}
// Chaque unité documentaire s'exporte dans un sous dossier "medias"
Path mediaFolderPath = Path.of(conf.getDeliveryFolder(), MEDIA_DIR);
String mediaFolder = mediaFolderPath.toString().replace('\\', '/');
sftpConf.setTargetDir(mediaFolder);
LOG.info("Envoi du document {}", mediasDirPath.getFileName());
sftpService.sftpPut(sftpConf, mediasDirPath.toAbsolutePath());
return true;
} catch (final PgcnTechnicalException e) {
LOG.error("Erreur de connexion sftp lors de l'export sur la Bibliothèque numérique");
return false;
}
}

@Transactional
public boolean exportFtp(final DigitalLibraryConfiguration conf, final boolean multiple, final boolean lastDoc, final File csv, final Path mediasDirPath) throws IOException,
PgcnTechnicalException {
final FTPClient ftpClient = new FTPClient();

ftpClient.connect(conf.getAddress(), Integer.parseInt(conf.getPort()));

final boolean success = ftpClient.login(conf.getLogin(), cryptoService.decrypt(conf.getPassword()));

if (!success) {
LOG.error("Erreur de connexion ftp lors de l'export sur la Bibliothèque numérique");
return false;
} else {
ftpClient.changeWorkingDirectory(conf.getDeliveryFolder());
if (!multiple || lastDoc) {
putPathRecursively(csv, ftpClient);
}
LOG.info("Envoi du document {}", mediasDirPath.getFileName());
putPathRecursively(mediasDirPath.toFile(), ftpClient);
ftpClient.logout();
ftpClient.disconnect();
return true;
}
}

@Transactional
public Pair<File, Path> exportDocUnit(final DocUnit docUnit,
final BibliographicRecordDcDTO metaDc,
final Path mediaDir,
final DigitalLibraryConfiguration conf,
final boolean multiple,
final boolean firstDoc) throws IOException, PgcnTechnicalException {

final Path root = mediaDir.resolve(docUnit.getPgcnId());
// Suppression du répertoire s'il existe
Expand All @@ -252,7 +299,7 @@ public File exportDocUnit(final DocUnit docUnit,
} catch (final PgcnUncheckedException e) {
throw new PgcnTechnicalException(e);
}
return csv;
return Pair.of(csv, depotPath);
}

private File createDocUnitsDigitalLibraryDiffusionCsv(final DocUnit docUnit,
Expand Down Expand Up @@ -543,10 +590,11 @@ private List<CheckSummedStoredFile> addDepotFiles(final DocUnit docUnit, final P
final StoredFile printStoredFile = print.get();
final File sourceFile = bm.getFileForStoredFile(printStoredFile, libraryId);
final Path sourcePath = Paths.get(sourceFile.getAbsolutePath());
final String fileName = printStoredFile.getFilename().substring(0, printStoredFile.getFilename().lastIndexOf(".") + 1) + ImageUtils.FORMAT_JPG;

if (conf.isExportPrint() && page.getNumber() != null) {
try {
final Path destPath = Files.createFile(depotPrint.resolve(printStoredFile.getFilename()));
final Path destPath = Files.createFile(depotPrint.resolve(fileName));
Files.copy(sourcePath, destPath, StandardCopyOption.REPLACE_EXISTING);
// On remplit la map pour optimiser le traitement ultérieur des métadonnées
checkSums.add(exportMetsService.getCheckSummedStoredFile(printStoredFile, sourceFile));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public void automaticOmekaExport() {

TransactionalJobRunner<String> job = new TransactionalJobRunner<>(docsToExport, transactionService);

job.setCommit(1).setReadOnly(true).setElementName("Doc Unit Exporting Omeka").forEach(docId -> {
job.setCommit(1).setReadOnly(false).setElementName("Doc Unit Exporting Omeka").forEach(docId -> {
boolean lastDoc = i.incrementAndGet() == docsToExport.size();
DocUnit doc = docUnitRepository.getReferenceById(docId);

Expand Down
Loading

0 comments on commit 6e03e1a

Please sign in to comment.