[Git][ultreiaio/ird-t3][develop] Marées sans logbooks : gestion de leurs échantillons - amélioration de…
Tony CHEMIT pushed to branch develop at ultreiaio / ird-t3 Commits: 61b98792 by Tony CHEMIT at 2018-03-09T12:02:40Z Marées sans logbooks : gestion de leurs échantillons - amélioration de l'interface uitlisation de configuration (See #116) - - - - - 14 changed files: - t3-actions/src/main/java/fr/ird/t3/actions/io/input/AnalyzeInputSourceConfiguration.java - t3-actions/src/main/java/fr/ird/t3/actions/io/input/ImportInputSourceAction.java - t3-actions/src/main/java/fr/ird/t3/actions/io/input/ImportInputSourceConfiguration.java - t3-actions/src/main/java/fr/ird/t3/actions/io/input/InputSourceConfiguration.java - t3-domain/src/main/java/fr/ird/t3/entities/data/TripType.java - t3-domain/src/main/java/fr/ird/t3/io/input/T3InputConfiguration.java - t3-web/src/main/java/fr/ird/t3/web/actions/io/input/AnalyzeImportDataAction.java - t3-web/src/main/java/fr/ird/t3/web/actions/io/input/ConfigureImportDataAction.java - t3-web/src/main/java/fr/ird/t3/web/actions/io/input/ImportDataAction.java - t3-web/src/main/resources/i18n/t3-web_en_GB.properties - t3-web/src/main/resources/i18n/t3-web_fr_FR.properties - t3-web/src/main/webapp/WEB-INF/jsp/io/input/analyzeImportDataResult.jsp - t3-web/src/main/webapp/WEB-INF/jsp/io/input/configureImportData.jsp - t3-web/src/main/webapp/WEB-INF/jsp/io/input/importDataConfigResume.jsp Changes: ===================================== t3-actions/src/main/java/fr/ird/t3/actions/io/input/AnalyzeInputSourceConfiguration.java ===================================== --- a/t3-actions/src/main/java/fr/ird/t3/actions/io/input/AnalyzeInputSourceConfiguration.java +++ b/t3-actions/src/main/java/fr/ird/t3/actions/io/input/AnalyzeInputSourceConfiguration.java @@ -8,12 +8,12 @@ * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * #L% @@ -43,22 +43,42 @@ public class AnalyzeInputSourceConfiguration implements InputSourceConfiguration protected boolean createVirtualVessel; protected T3InputProvider inputProvider; protected File inputFile; + /** + * Flag to load only samples only trips + * + * @see TripType#SAMPLEONLY + */ + private boolean useSamplesOnly; + /** + * Flag to authorize virtual activity creation (when logbooks are missing). + * <p> + * By default, let's always authorize it. + * <p> + * <b>Note:</b> This option is always at false if {@link #useSamplesOnly} is on. + * + * @see TripType#LOGBOOKMISSING + * @see TripType#STANDARD + */ + private boolean canCreateVirtualActivity; private TripType tripType; public static AnalyzeInputSourceConfiguration newConfiguration( T3InputProvider inputProvider, File inputFile, boolean useWells, - TripType tripType, boolean canCreateVessel, - boolean createVirtualVessel) { + boolean createVirtualVessel, + boolean useSamplesOnly, + boolean canCreateVirtualActivity) { AnalyzeInputSourceConfiguration result = new AnalyzeInputSourceConfiguration(); result.setInputFile(inputFile); result.setInputProvider(inputProvider); result.setUseWells(useWells); - result.setTripType(tripType); + result.setTripType(TripType.getTripType(useSamplesOnly, canCreateVirtualActivity)); result.setCanCreateVessel(canCreateVessel); result.setCreateVirtualVessel(createVirtualVessel); + result.setCanCreateVirtualActivity(canCreateVirtualActivity); + result.setUseSamplesOnly(useSamplesOnly); return result; } @@ -127,12 +147,34 @@ public class AnalyzeInputSourceConfiguration implements InputSourceConfiguration return l(locale, "t3.input.AnalyzeInputSource"); } + @Override + public boolean isUseSamplesOnly() { + return useSamplesOnly; + } + + @Override + public void setUseSamplesOnly(boolean useSamplesOnly) { + this.useSamplesOnly = useSamplesOnly; + } + + @Override + public boolean isCanCreateVirtualActivity() { + return canCreateVirtualActivity; + } + + @Override + public void setCanCreateVirtualActivity(boolean canCreateVirtualActivity) { + this.canCreateVirtualActivity = canCreateVirtualActivity; + } + T3InputConfiguration toInputConfiguration() { T3InputConfiguration result = new T3InputConfiguration(); result.setCanCreateVessel(canCreateVessel); result.setCreateVirtualVessel(createVirtualVessel); result.setTripType(tripType); result.setUseWells(useWells); + result.setCanCreateVirtualActivity(canCreateVirtualActivity); + result.setUseSamplesOnly(useSamplesOnly); result.setInputFile(inputFile); return result; } ===================================== t3-actions/src/main/java/fr/ird/t3/actions/io/input/ImportInputSourceAction.java ===================================== --- a/t3-actions/src/main/java/fr/ird/t3/actions/io/input/ImportInputSourceAction.java +++ b/t3-actions/src/main/java/fr/ird/t3/actions/io/input/ImportInputSourceAction.java @@ -25,7 +25,6 @@ import fr.ird.t3.entities.T3EntityEnum; import fr.ird.t3.entities.T3TopiaApplicationContext; import fr.ird.t3.entities.T3TopiaPersistenceContext; import fr.ird.t3.entities.data.Activity; -import fr.ird.t3.entities.data.ActivityTopiaDao; import fr.ird.t3.entities.data.T3DataEntity; import fr.ird.t3.entities.data.Trip; import fr.ird.t3.entities.data.TripTopiaDao; @@ -60,15 +59,11 @@ import static org.nuiton.i18n.I18n.l; */ public class ImportInputSourceAction extends T3Action<ImportInputSourceConfiguration> { - // public static final String PARAM_TRIPS_TO_IMPORT = "tripsToImport"; -// public static final String PARAM_TRIPS_TO_DELETE = "tripsToDelete"; private static final Log log = LogFactory.getLog(ImportInputSourceAction.class); @InjectDAO(entityType = Trip.class) private TripTopiaDao tripDAO; @InjectDAO(entityType = Vessel.class) private VesselTopiaDao vesselDAO; - @InjectDAO(entityType = Activity.class) - private ActivityTopiaDao activityDAO; @InjectDAO(entityType = Ocean.class) private OceanTopiaDao oceanDAO; private Set<Trip> tripToDelete; @@ -88,13 +83,10 @@ public class ImportInputSourceAction extends T3Action<ImportInputSourceConfigura @Override protected boolean executeAction() { - if (CollectionUtils.isEmpty(trips)) { - // no trips at all to import - // no commit to do, skip the action + // no trips at all to import, no commit to do, skip the action return false; } - int nbSteps = 0; if (CollectionUtils.isNotEmpty(trips)) { nbSteps += trips.size(); @@ -102,7 +94,6 @@ public class ImportInputSourceAction extends T3Action<ImportInputSourceConfigura if (CollectionUtils.isNotEmpty(tripToDelete)) { nbSteps += tripToDelete.size(); } - setNbSteps(nbSteps); log.info(String.format("Nb steps : %d", getNbSteps())); if (CollectionUtils.isNotEmpty(tripToDelete)) { @@ -154,8 +145,6 @@ public class ImportInputSourceAction extends T3Action<ImportInputSourceConfigura // Need to flush as we are going to query new data getT3TopiaPersistenceContext().get().getHibernateSupport().getHibernateSession().flush(); - - String prefix = Activity.class.getName() + "#"; for (Activity activity : ids) { Ocean ocean = oceanDAO.findOceanByActivity(activity); activity.setOcean(ocean); ===================================== t3-actions/src/main/java/fr/ird/t3/actions/io/input/ImportInputSourceConfiguration.java ===================================== --- a/t3-actions/src/main/java/fr/ird/t3/actions/io/input/ImportInputSourceConfiguration.java +++ b/t3-actions/src/main/java/fr/ird/t3/actions/io/input/ImportInputSourceConfiguration.java @@ -8,12 +8,12 @@ * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * #L% @@ -45,6 +45,23 @@ public class ImportInputSourceConfiguration implements InputSourceConfiguration protected boolean createVirtualVessel; protected T3InputProvider inputProvider; protected File inputFile; + /** + * Flag to load only samples only trips + * + * @see TripType#SAMPLEONLY + */ + private boolean useSamplesOnly; + /** + * Flag to authorize virtual activity creation (when logbooks are missing). + * <p> + * By default, let's always authorize it. + * <p> + * <b>Note:</b> This option is always at false if {@link #useSamplesOnly} is on. + * + * @see TripType#LOGBOOKMISSING + * @see TripType#STANDARD + */ + private boolean canCreateVirtualActivity; private Set<Trip> tripsToImport; private Set<Trip> tripsToDelete; @@ -124,6 +141,27 @@ public class ImportInputSourceConfiguration implements InputSourceConfiguration return l(locale, "t3.input.ImportInputSource"); } + + @Override + public boolean isUseSamplesOnly() { + return useSamplesOnly; + } + + @Override + public void setUseSamplesOnly(boolean useSamplesOnly) { + this.useSamplesOnly = useSamplesOnly; + } + + @Override + public boolean isCanCreateVirtualActivity() { + return canCreateVirtualActivity; + } + + @Override + public void setCanCreateVirtualActivity(boolean canCreateVirtualActivity) { + this.canCreateVirtualActivity = canCreateVirtualActivity; + } + public Set<Trip> getTripsToImport() { return tripsToImport; } ===================================== t3-actions/src/main/java/fr/ird/t3/actions/io/input/InputSourceConfiguration.java ===================================== --- a/t3-actions/src/main/java/fr/ird/t3/actions/io/input/InputSourceConfiguration.java +++ b/t3-actions/src/main/java/fr/ird/t3/actions/io/input/InputSourceConfiguration.java @@ -50,6 +50,14 @@ public interface InputSourceConfiguration extends T3ActionConfiguration { void setCreateVirtualVessel(boolean createVirtualVessel); + boolean isUseSamplesOnly(); + + void setUseSamplesOnly(boolean useSamplesOnly); + + boolean isCanCreateVirtualActivity(); + + void setCanCreateVirtualActivity(boolean canCreateVirtualActivity); + T3InputProvider getInputProvider(); void setInputProvider(T3InputProvider inputProvider); ===================================== t3-domain/src/main/java/fr/ird/t3/entities/data/TripType.java ===================================== --- a/t3-domain/src/main/java/fr/ird/t3/entities/data/TripType.java +++ b/t3-domain/src/main/java/fr/ird/t3/entities/data/TripType.java @@ -10,12 +10,12 @@ package fr.ird.t3.entities.data; * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * #L% @@ -23,13 +23,21 @@ package fr.ird.t3.entities.data; import fr.ird.t3.t3.domain.I18nEnumHelper; -import static org.nuiton.i18n.I18n.t; - public enum TripType { STANDARD, SAMPLEONLY, LOGBOOKMISSING; + public static TripType getTripType(boolean useSamplesOnly, boolean canCreateVirtualActivity) { + TripType tripType; + if (useSamplesOnly) { + tripType = SAMPLEONLY; + } else { + tripType = canCreateVirtualActivity ? LOGBOOKMISSING : STANDARD; + } + return tripType; + } + public String getLabel() { return I18nEnumHelper.getLabel(this); } ===================================== t3-domain/src/main/java/fr/ird/t3/io/input/T3InputConfiguration.java ===================================== --- a/t3-domain/src/main/java/fr/ird/t3/io/input/T3InputConfiguration.java +++ b/t3-domain/src/main/java/fr/ird/t3/io/input/T3InputConfiguration.java @@ -8,12 +8,12 @@ * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * #L% @@ -33,15 +33,13 @@ import java.io.File; */ public class T3InputConfiguration { - protected boolean useWells; - - protected boolean canCreateVessel; - - protected boolean createVirtualVessel; - - protected TripType tripType; - - protected File inputFile; + private boolean useWells; + private boolean canCreateVessel; + private boolean createVirtualVessel; + private boolean useSamplesOnly; + private boolean canCreateVirtualActivity; + private TripType tripType; + private File inputFile; private T3TopiaApplicationContext topiaApplicationContext; @@ -85,6 +83,22 @@ public class T3InputConfiguration { this.inputFile = inputFile; } + public boolean isUseSamplesOnly() { + return useSamplesOnly; + } + + public void setUseSamplesOnly(boolean useSamplesOnly) { + this.useSamplesOnly = useSamplesOnly; + } + + public boolean isCanCreateVirtualActivity() { + return canCreateVirtualActivity; + } + + public void setCanCreateVirtualActivity(boolean canCreateVirtualActivity) { + this.canCreateVirtualActivity = canCreateVirtualActivity; + } + public T3TopiaApplicationContext getTopiaApplicationContext() { return topiaApplicationContext; } ===================================== t3-web/src/main/java/fr/ird/t3/web/actions/io/input/AnalyzeImportDataAction.java ===================================== --- a/t3-web/src/main/java/fr/ird/t3/web/actions/io/input/AnalyzeImportDataAction.java +++ b/t3-web/src/main/java/fr/ird/t3/web/actions/io/input/AnalyzeImportDataAction.java @@ -8,12 +8,12 @@ * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * #L% @@ -27,13 +27,14 @@ import fr.ird.t3.entities.data.Trip; import fr.ird.t3.io.input.T3InputProvider; import fr.ird.t3.services.DecoratorService; import fr.ird.t3.web.actions.AbstractRunAction; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections.MapUtils; + import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Set; -import org.apache.commons.collections.CollectionUtils; -import org.apache.commons.collections.MapUtils; /** * Analyze the given input source. @@ -45,15 +46,11 @@ public class AnalyzeImportDataAction extends AbstractRunAction<AnalyzeInputSourc private static final long serialVersionUID = 1L; - protected int nbUnsafeTrips; - - protected int nbSafeTrips; - - protected int nbTripsToReplace; - - protected boolean needReplace; - - protected boolean valid; + private int nbUnsafeTrips; + private int nbSafeTrips; + private int nbTripsToReplace; + private boolean needReplace; + private boolean valid; /** List of all known input providers. */ private List<T3InputProvider> inputProviders; @@ -64,111 +61,75 @@ public class AnalyzeImportDataAction extends AbstractRunAction<AnalyzeInputSourc @Override public void prepare() throws Exception { - getT3Session().removeTripListModel(); - super.prepare(); - inputProviders = Collections.singletonList(getConfiguration().getInputProvider()); } - public final List<T3InputProvider> getInputProviders() { - return inputProviders; - } - public String prepareResult() { - - T3ActionContext<AnalyzeInputSourceConfiguration> context = - getT3ActionContext(); - - Set<Trip> safeTrips = context.getResultAsSet( - AnalyzeInputSourceAction.RESULT_SAFE_TRIPS, - Trip.class - ); + T3ActionContext<AnalyzeInputSourceConfiguration> context = getT3ActionContext(); + Set<Trip> safeTrips = context.getResultAsSet(AnalyzeInputSourceAction.RESULT_SAFE_TRIPS, Trip.class); nbSafeTrips = safeTrips.size(); - - Set<Trip> unsafeTrips = context.getResultAsSet( - AnalyzeInputSourceAction.RESULT_UNSAFE_TRIPS, - Trip.class - ); + Set<Trip> unsafeTrips = context.getResultAsSet(AnalyzeInputSourceAction.RESULT_UNSAFE_TRIPS, Trip.class); nbUnsafeTrips = unsafeTrips.size(); - - boolean canImport = CollectionUtils.isEmpty(unsafeTrips) && - CollectionUtils.isNotEmpty(safeTrips); - + boolean canImport = CollectionUtils.isEmpty(unsafeTrips) && CollectionUtils.isNotEmpty(safeTrips); // action is valid, only if there is some safe trips and no unsafe trip valid = canImport; - Map<Trip, Trip> tripsToReplace; - if (canImport) { - // find out if there is some existing trip to re-import - - tripsToReplace = context.getResultAsMap( - AnalyzeInputSourceAction.RESULT_TRIPS_TO_REPLACE - ); + tripsToReplace = context.getResultAsMap(AnalyzeInputSourceAction.RESULT_TRIPS_TO_REPLACE); } else { - // no trip to replace tripsToReplace = Collections.emptyMap(); } - nbTripsToReplace = tripsToReplace.size(); - needReplace = MapUtils.isNotEmpty(tripsToReplace); - return INPUT; } + @Override + protected Map<String, Object> prepareResumeParameters(AnalyzeInputSourceAction action, Exception error, Date startDate, Date endDate) { + Map<String, Object> map = super.prepareResumeParameters(action, error, startDate, endDate); + T3ActionContext<AnalyzeInputSourceConfiguration> actionContext = getT3ActionContext(); + Set<Trip> safeTrips = actionContext.getResultAsSet(AnalyzeInputSourceAction.RESULT_SAFE_TRIPS, Trip.class); + map.put(AnalyzeInputSourceAction.RESULT_SAFE_TRIPS, safeTrips); + Set<Trip> unsafeTrips = actionContext.getResultAsSet(AnalyzeInputSourceAction.RESULT_UNSAFE_TRIPS, Trip.class); + map.put(AnalyzeInputSourceAction.RESULT_UNSAFE_TRIPS, unsafeTrips); + Map<Trip, Trip> tripsToReplace = actionContext.getResultAsMap(AnalyzeInputSourceAction.RESULT_TRIPS_TO_REPLACE); + map.put(AnalyzeInputSourceAction.RESULT_TRIPS_TO_REPLACE, tripsToReplace); + map.put("tripDecorator", getDecorator(Trip.class)); + map.put("tripDecorator2", getDecorator(Trip.class, DecoratorService.WITH_ID)); + return map; + } + + @SuppressWarnings("unused") + public List<T3InputProvider> getInputProviders() { + return inputProviders; + } + + @SuppressWarnings("unused") public int getNbUnsafeTrips() { return nbUnsafeTrips; } + @SuppressWarnings("unused") public int getNbSafeTrips() { return nbSafeTrips; } + @SuppressWarnings("unused") public int getNbTripsToReplace() { return nbTripsToReplace; } + @SuppressWarnings("unused") public boolean isValid() { return valid; } + @SuppressWarnings("unused") public boolean isNeedReplace() { return needReplace; } - - @Override - protected Map<String, Object> prepareResumeParameters(AnalyzeInputSourceAction action, - Exception error, - Date startDate, - Date endDate) { - Map<String, Object> map = super.prepareResumeParameters(action, error, startDate, endDate); - - T3ActionContext<AnalyzeInputSourceConfiguration> actionContext = getT3ActionContext(); - - Set<Trip> safeTrips = actionContext.getResultAsSet( - AnalyzeInputSourceAction.RESULT_SAFE_TRIPS, - Trip.class - ); - map.put(AnalyzeInputSourceAction.RESULT_SAFE_TRIPS, safeTrips); - Set<Trip> unsafeTrips = actionContext.getResultAsSet( - AnalyzeInputSourceAction.RESULT_UNSAFE_TRIPS, - Trip.class - ); - map.put(AnalyzeInputSourceAction.RESULT_UNSAFE_TRIPS, unsafeTrips); - Map<Trip, Trip> tripsToReplace = actionContext.getResultAsMap( - AnalyzeInputSourceAction.RESULT_TRIPS_TO_REPLACE - ); - map.put(AnalyzeInputSourceAction.RESULT_TRIPS_TO_REPLACE, tripsToReplace); - - map.put("tripDecorator", getDecorator(Trip.class)); - - map.put("tripDecorator2", - getDecorator(Trip.class, DecoratorService.WITH_ID)); - return map; - } } ===================================== t3-web/src/main/java/fr/ird/t3/web/actions/io/input/ConfigureImportDataAction.java ===================================== --- a/t3-web/src/main/java/fr/ird/t3/web/actions/io/input/ConfigureImportDataAction.java +++ b/t3-web/src/main/java/fr/ird/t3/web/actions/io/input/ConfigureImportDataAction.java @@ -8,12 +8,12 @@ * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * #L% @@ -55,22 +55,21 @@ import java.util.zip.ZipFile; */ public class ConfigureImportDataAction extends AbstractConfigureAction<AnalyzeInputSourceConfiguration> { - // public static final String RELOAD_ACTION = "reload"; private static final long serialVersionUID = 1L; private static final Log log = LogFactory.getLog(ConfigureImportDataAction.class); - /** Input file that was just uploaded on server */ + /** + * Input file that was just uploaded on server. + */ private File sourceToLoad; - /** Name of file to upload */ + /** + * Name of file to upload. + */ private String sourceToLoadFileName; - /** flag to use strict mode with wells. */ - private boolean useWells; /** - * Trip type to use - * - * @since 2.3 + * Flag to use strict mode with wells. */ - private TripType tripType = TripType.STANDARD; + private boolean useWells; /** * flag to authorize creation of missing vessels. * @@ -83,6 +82,24 @@ public class ConfigureImportDataAction extends AbstractConfigureAction<AnalyzeIn * @since 1.3.1 */ private boolean createVirtualVessel; + /** + * Flag to load only samples only trips + * + * @see TripType#SAMPLEONLY + */ + private boolean useSamplesOnly; + /** + * Flag to authorize virtual activity creation (when logbooks are missing). + * <p> + * By default, let's always authorize it. + * <p> + * <b>Note:</b> This option is always at false if {@link #useSamplesOnly} is on. + * + * @see TripType#LOGBOOKMISSING + * @see TripType#STANDARD + */ + private boolean canCreateVirtualActivity; + private long maxSize; /** List of all known input providers. */ private List<T3InputProvider> inputProviders; @@ -100,139 +117,79 @@ public class ConfigureImportDataAction extends AbstractConfigureAction<AnalyzeIn super(AnalyzeInputSourceConfiguration.class); } - public String getMaxSize() { - return StringUtil.convertMemory(maxSize); - } - - @Inject(StrutsConstants.STRUTS_MULTIPART_MAXSIZE) - public void setMaxSize(String maxSize) { - this.maxSize = Long.parseLong(maxSize); - } - @Override public void prepare() throws Exception { - injectOnly(InjectDAO.class); - if (!isConfigurationInSession()) { - // no yet configuration, can use all input providers inputProviders = Arrays.asList(getT3InputService().getProviders()); - } else { - // as soon as there is a configuration, can only use the - // inputProvider from it - + // as soon as there is a configuration, can only use the inputProvider from it inputProviders = Collections.singletonList(getConfiguration().getInputProvider()); } - injectOnly(InjectDecoratedBeans.class); - if (getTreatmentDirectoryPath() == null) { - // first time coming here get a new treatment directory path - File workingDirectory = getApplicationConfig().getTreatmentWorkingDirectory(); - long l = System.nanoTime(); - File treatmentDirectory = new File(workingDirectory, "importData-" + l); - FileUtil.createDirectoryIfNecessary(treatmentDirectory); - - if (log.isInfoEnabled()) { - log.info(String.format("Create a new treatment directory path : %s", treatmentDirectory)); - } - + log.info(String.format("Create a new treatment directory path : %s", treatmentDirectory)); setTreatmentDirectoryPath(treatmentDirectory.getAbsolutePath()); } else { - - if (log.isInfoEnabled()) { - log.info(String.format("Use existing treatment directory %s", getTreatmentDirectoryPath())); - } + log.info(String.format("Use existing treatment directory %s", getTreatmentDirectoryPath())); } } public String doAddSource() throws Exception { - - // this action execution purpose is to add a new source to the - // treatment configuration - // It will upload the file and place it the correct place (says the - // temporary directory of the treatment configuration) - - // file uploaded on server + // this action execution purpose is to add a new source to the treatment configuration + // It will upload the file and place it the correct place (says the temporary directory of the treatment configuration) File upload = getSourceToLoad(); - if (upload == null) { - String message = t("t3.error.required.file.to.upload"); addFieldError("sourceToLoad", message); log.error(message); return ERROR; } - // treatment directory File targetDirectory = getTreatmentDirectory(); - String filename = getSourceToLoadFileName(); - if (ZipUtil.isZipFile(upload)) { - // let's decompress input stream it ZipFile zipfile = new ZipFile(upload); - Enumeration<? extends ZipEntry> entries = zipfile.entries(); - if (!entries.hasMoreElements()) { String message = t("t3.error.required.one.entry.in.zip.to.upload"); addFieldError("sourceToLoad", message); log.error(message); return ERROR; } - // get first entry ZipEntry zipEntry = entries.nextElement(); - // keep the filename of the zip entry filename = zipEntry.getName(); - File target = new File(targetDirectory, filename); - - if (log.isInfoEnabled()) { - log.info(String.format("Will copy loaded zipped entry file %s to treatment configuration directory %s", filename, target)); - } + log.info(String.format("Will copy loaded zipped entry file %s to treatment configuration directory %s", filename, target)); try (InputStream in = zipfile.getInputStream(zipEntry)) { FileUtils.copyInputStreamToFile(in, target); } } else { - // target file File target = new File(targetDirectory, filename); - - if (log.isInfoEnabled()) { - log.info(String.format("Will copy loaded file %s to treatment configuration directory %s", upload, target)); - } - + log.info(String.format("Will copy loaded file %s to treatment configuration directory %s", upload, target)); // just copy file FileUtils.copyFile(upload, target); } - // add the new file to the sources setLoadedSource(filename); - // go back to the configuration definition return INPUT; } public String doDeleteSource() throws Exception { - String filename = getLoadedSource(); - File targetDirectory = getTreatmentDirectory(); - - if (log.isInfoEnabled()) { - log.info(String.format("Will delete loaded file %s from %s", filename, targetDirectory)); - } + log.info(String.format("Will delete loaded file %s from %s", filename, targetDirectory)); File f = new File(targetDirectory, filename); if (f.exists()) { boolean delete = f.delete(); @@ -240,9 +197,7 @@ public class ConfigureImportDataAction extends AbstractConfigureAction<AnalyzeIn throw new IOException(String.format("Could not delete file %s on server.", f)); } } - setLoadedSource(null); - // go back to the configuration definition return INPUT; } @@ -251,107 +206,143 @@ public class ConfigureImportDataAction extends AbstractConfigureAction<AnalyzeIn T3InputProvider inputProvider = getT3InputService().getProvider(getInputProviderId()); File path = getTreatmentDirectory(); String name = getLoadedSource(); - File inputFile = new File(path, name); - - if (log.isInfoEnabled()) { - log.info(String.format("Will use input provider : %s", inputProvider)); - log.info(String.format("Will use input file : %s", inputFile)); - } - - // prepare a new action configuration - configuration = AnalyzeInputSourceConfiguration.newConfiguration( - inputProvider, - inputFile, - useWells, - tripType, - canCreateVessel, - createVirtualVessel); - + TripType tripType = TripType.getTripType(useSamplesOnly, canCreateVirtualActivity); + log.info(String.format("input provider : %s", inputProvider)); + log.info(String.format("input file : %s", inputFile)); + log.info(String.format("userWells : %s", useWells)); + log.info(String.format("tripType : %s", tripType)); + log.info(String.format("canCreateVessel : %s", canCreateVessel)); + log.info(String.format("createVirtualVessel : %s", createVirtualVessel)); + log.info(String.format("canCreateVirtualActivity : %s", canCreateVirtualActivity)); + log.info(String.format("useSamplesOnly : %s", useSamplesOnly)); + configuration = AnalyzeInputSourceConfiguration.newConfiguration(inputProvider, inputFile, useWells, canCreateVessel, createVirtualVessel, useSamplesOnly, canCreateVirtualActivity); prepareActionContext(); return SUCCESS; } - public TripType getTripType() { - return tripType; + @SuppressWarnings("unused") + public String getMaxSize() { + return StringUtil.convertMemory(maxSize); } - public void setTripType(TripType tripType) { - this.tripType = tripType; + @SuppressWarnings("unused") + @Inject(StrutsConstants.STRUTS_MULTIPART_MAXSIZE) + public void setMaxSize(String maxSize) { + this.maxSize = Long.parseLong(maxSize); } + @SuppressWarnings("unused") public Map<String, String> getTripTypes() { return tripTypes; } + @SuppressWarnings("unused") public void setTripTypes(Map<String, String> tripTypes) { this.tripTypes = tripTypes; } + @SuppressWarnings({"unused", "WeakerAccess"}) public File getSourceToLoad() { return sourceToLoad; } + @SuppressWarnings("unused") public void setSourceToLoad(File sourceToLoad) { this.sourceToLoad = sourceToLoad; } + @SuppressWarnings({"unused", "WeakerAccess"}) public String getSourceToLoadFileName() { return sourceToLoadFileName; } + @SuppressWarnings("unused") public void setSourceToLoadFileName(String sourceToLoadFileName) { this.sourceToLoadFileName = sourceToLoadFileName; } + @SuppressWarnings("unused") public boolean isUseWells() { return useWells; } + @SuppressWarnings("unused") public void setUseWells(boolean useWells) { this.useWells = useWells; } + @SuppressWarnings("unused") public boolean isCanCreateVessel() { return canCreateVessel; } + @SuppressWarnings("unused") public void setCanCreateVessel(boolean canCreateVessel) { this.canCreateVessel = canCreateVessel; } + @SuppressWarnings("unused") public boolean isCreateVirtualVessel() { return createVirtualVessel; } + @SuppressWarnings("unused") public void setCreateVirtualVessel(boolean createVirtualVessel) { this.createVirtualVessel = createVirtualVessel; } + @SuppressWarnings({"unused", "WeakerAccess"}) public String getInputProviderId() { return inputProviderId; } + @SuppressWarnings("unused") public void setInputProviderId(String inputProviderId) { this.inputProviderId = inputProviderId; } + @SuppressWarnings({"unused", "WeakerAccess"}) public String getLoadedSource() { return loadedSource; } + @SuppressWarnings({"unused", "WeakerAccess"}) public void setLoadedSource(String loadedSource) { this.loadedSource = loadedSource; } + @SuppressWarnings({"unused", "WeakerAccess"}) public String getTreatmentDirectoryPath() { return treatmentDirectoryPath; } + @SuppressWarnings({"unused", "WeakerAccess"}) public void setTreatmentDirectoryPath(String treatmentDirectoryPath) { this.treatmentDirectoryPath = treatmentDirectoryPath; } + @SuppressWarnings("unused") + public boolean isUseSamplesOnly() { + return useSamplesOnly; + } + + @SuppressWarnings("unused") + public void setUseSamplesOnly(boolean useSamplesOnly) { + this.useSamplesOnly = useSamplesOnly; + } + + @SuppressWarnings("unused") + public boolean isCanCreateVirtualActivity() { + return canCreateVirtualActivity; + } + + @SuppressWarnings("unused") + public void setCanCreateVirtualActivity(boolean canCreateVirtualActivity) { + this.canCreateVirtualActivity = canCreateVirtualActivity; + } + + @SuppressWarnings("unused") public final List<T3InputProvider> getInputProviders() { return inputProviders; } ===================================== t3-web/src/main/java/fr/ird/t3/web/actions/io/input/ImportDataAction.java ===================================== --- a/t3-web/src/main/java/fr/ird/t3/web/actions/io/input/ImportDataAction.java +++ b/t3-web/src/main/java/fr/ird/t3/web/actions/io/input/ImportDataAction.java @@ -49,15 +49,15 @@ import java.util.Set; public class ImportDataAction extends AbstractRunAction<ImportInputSourceConfiguration, ImportInputSourceAction> { private static final long serialVersionUID = 1L; - private static final Log log = LogFactory.getLog(ImportDataAction.class); private boolean replaceTrip; private boolean valid; private int nbImportedTrips; private int nbDeletedTrips; - - /** List of all known input providers. */ + /** + * List of all known input providers. + */ private List<T3InputProvider> inputProviders; public ImportDataAction() { @@ -70,132 +70,101 @@ public class ImportDataAction extends AbstractRunAction<ImportInputSourceConfigu inputProviders = Collections.singletonList(getIncomingConfiguration().getInputProvider()); } - public final List<T3InputProvider> getInputProviders() { - return inputProviders; - } - - public InputSourceConfiguration getIncomingConfiguration() { - Object configuration = getT3ActionContext().getConfiguration(); - return (InputSourceConfiguration) configuration; - } - public String prepareImport() { - // get the action context from analyze - - T3ActionContext<ImportInputSourceConfiguration> actionContext = - getT3ActionContext(); - - Set<Trip> safeTrips = actionContext.getResultAsSet( - AnalyzeInputSourceAction.RESULT_SAFE_TRIPS, - Trip.class); - - Map<Trip, Trip> tripToReplace = actionContext.getResultAsMap( - AnalyzeInputSourceAction.RESULT_TRIPS_TO_REPLACE - ); - - if (log.isInfoEnabled()) { - log.info("--> Prepare import"); - log.info("Input provider : " + getIncomingConfiguration().getInputProvider()); - log.info("Input file : " + getIncomingConfiguration().getInputFile()); - log.info("Use well : " + getIncomingConfiguration().isUseWells()); - log.info("Trip type : " + getIncomingConfiguration().getTripType()); - log.info("Can Create vessel: " + getIncomingConfiguration().isCanCreateVessel()); - if (getIncomingConfiguration().isCanCreateVessel()) { - log.info("Create virtual vessel: " + getIncomingConfiguration().isCreateVirtualVessel()); - } - log.info("Trips to import : " + safeTrips.size()); - log.info("Trips to replace : " + tripToReplace.size()); + T3ActionContext<ImportInputSourceConfiguration> actionContext = getT3ActionContext(); + Set<Trip> safeTrips = actionContext.getResultAsSet(AnalyzeInputSourceAction.RESULT_SAFE_TRIPS, Trip.class); + Map<Trip, Trip> tripToReplace = actionContext.getResultAsMap(AnalyzeInputSourceAction.RESULT_TRIPS_TO_REPLACE); + log.info("--> Prepare import"); + log.info("Input provider : " + getIncomingConfiguration().getInputProvider()); + log.info("Input file : " + getIncomingConfiguration().getInputFile()); + log.info("Use well : " + getIncomingConfiguration().isUseWells()); + log.info("Trip type : " + getIncomingConfiguration().getTripType()); + log.info("Can Create vessel: " + getIncomingConfiguration().isCanCreateVessel()); + if (getIncomingConfiguration().isCanCreateVessel()) { + log.info("Create virtual vessel: " + getIncomingConfiguration().isCreateVirtualVessel()); } - + log.info("Trips to import : " + safeTrips.size()); + log.info("Trips to replace : " + tripToReplace.size()); Set<Trip> toImportTrips = new HashSet<>(); Set<Trip> toDeleteTrips = new HashSet<>(); - if (isReplaceTrip()) { - - // will replace existing trips - // so need to delete before all old trips + // will replace existing trips, so need to delete before all old trips toDeleteTrips.addAll(tripToReplace.keySet()); - // can import all safe trips toImportTrips.addAll(safeTrips); - } else { - // do NOT replace old trip - // get all importable trips toImportTrips.addAll(safeTrips); - if (MapUtils.isNotEmpty(tripToReplace)) { - // remove the one which reflect existing trips toImportTrips.removeAll(tripToReplace.values()); } } - // creates the new configuration - ImportInputSourceConfiguration configuration = ImportInputSourceConfiguration.newConfiguration(getIncomingConfiguration()); - configuration.setTripsToImport(toImportTrips); - configuration.setTripsToDelete(toDeleteTrips); - - t3ActionContext = getServiceFactory().newT3ActionContext(configuration, getServiceContext() - ); - if (log.isInfoEnabled()) { - log.info("Created action context " + t3ActionContext); - } + t3ActionContext = getServiceFactory().newT3ActionContext(configuration, getServiceContext()); + log.info("Created action context " + t3ActionContext); getT3Session().setActionContext(t3ActionContext); - return SUCCESS; } public String prepareResult() { - Set<Trip> importedTrips = getConfiguration().getTripsToImport(); - nbImportedTrips = importedTrips.size(); + Set<Trip> deletedTrips = getConfiguration().getTripsToDelete(); + nbDeletedTrips = deletedTrips.size(); + return INPUT; + } - Set<Trip> deletedeTrips = getConfiguration().getTripsToDelete(); + @Override + protected Map<String, Object> prepareResumeParameters(ImportInputSourceAction action, Exception error, Date startDate, Date endDate) { + Map<String, Object> map = super.prepareResumeParameters(action, error, startDate, endDate); + map.put("tripDecorator", getDecorator(Trip.class, DecoratorService.WITH_ID)); + return map; + } - nbDeletedTrips = deletedeTrips.size(); + @SuppressWarnings("unused") + public List<T3InputProvider> getInputProviders() { + return inputProviders; + } - return INPUT; + @SuppressWarnings("WeakerAccess") + public InputSourceConfiguration getIncomingConfiguration() { + Object configuration = getT3ActionContext().getConfiguration(); + return (InputSourceConfiguration) configuration; } + @SuppressWarnings("unused") public boolean isValid() { return valid; } + @SuppressWarnings("unused") public void setValid(boolean valid) { this.valid = valid; } + @SuppressWarnings("unused") public int getNbImportedTrips() { return nbImportedTrips; } + @SuppressWarnings("unused") public int getNbDeletedTrips() { return nbDeletedTrips; } + @SuppressWarnings("WeakerAccess") public boolean isReplaceTrip() { return replaceTrip; } + @SuppressWarnings("unused") public void setReplaceTrip(boolean replaceTrip) { this.replaceTrip = replaceTrip; } - - @Override - protected Map<String, Object> prepareResumeParameters(ImportInputSourceAction action, - Exception error, - Date startDate, - Date endDate) { - Map<String, Object> map = super.prepareResumeParameters(action, error, startDate, endDate); - map.put("tripDecorator", getDecorator(Trip.class, DecoratorService.WITH_ID)); - return map; - } } ===================================== t3-web/src/main/resources/i18n/t3-web_en_GB.properties ===================================== --- a/t3-web/src/main/resources/i18n/t3-web_en_GB.properties +++ b/t3-web/src/main/resources/i18n/t3-web_en_GB.properties @@ -1,3 +1,4 @@ +t3.common.canCreateVirtualActivity=Authorize to create virtaul activities (for trips with missing logbook) t3.action.applyFilter=Apply t3.action.back.to.configuration.step1=Back to step 1 of configuration t3.action.back.to.configuration.step2=Back to step 2 of configuration ===================================== t3-web/src/main/resources/i18n/t3-web_fr_FR.properties ===================================== --- a/t3-web/src/main/resources/i18n/t3-web_fr_FR.properties +++ b/t3-web/src/main/resources/i18n/t3-web_fr_FR.properties @@ -13,6 +13,7 @@ t3.action.delete=Supprimer t3.action.deleteComputedData=Suppression des données calculées t3.action.deleteTrips=Suppression des marées t3.action.detail=Détails +t3.common.canCreateVirtualActivity=Autoriser la création d'acitivités fictive (pour les marées sans livre de bord) t3.action.dolog=S'authentifier t3.action.edit=Editer t3.action.getUserLog=Télécharger le fichier de logs ===================================== t3-web/src/main/webapp/WEB-INF/jsp/io/input/analyzeImportDataResult.jsp ===================================== --- a/t3-web/src/main/webapp/WEB-INF/jsp/io/input/analyzeImportDataResult.jsp +++ b/t3-web/src/main/webapp/WEB-INF/jsp/io/input/analyzeImportDataResult.jsp @@ -29,9 +29,7 @@ <jsp:include page="importDataConfigResume.jsp"/> <s:if test="valid"> - <%-- Can do the import --%> - <p> <s:text name="t3.label.message.trips.safe.to.import"> <s:param> @@ -39,27 +37,20 @@ </s:param> </s:text> </p> - - <s:form method="post" validate="true" namespace="/io"> + <s:form method="post" validate="true" namespace="/io"> <s:if test="needReplace"> <strong> - <s:text name="t3.label.message.trips.to.replace"> - <s:param> - <s:property value="%{nbTripsToReplace}"/> - </s:param> - </s:text> + <s:text name="t3.label.message.trips.to.replace"> + <s:param> + <s:property value="%{nbTripsToReplace}"/> + </s:param> + </s:text> </strong> <s:checkbox name="replaceTrip" key="t3.question.confirm.to.replace.trip" value="%{false}"/> - </s:if> - - <s:submit action="prepareImportData" - key="t3.action.importData.doImport" - align="right"/> - + <s:submit action="prepareImportData" key="t3.action.importData.doImport" align="right"/> </s:form> - </s:if> <s:else> <p> ===================================== t3-web/src/main/webapp/WEB-INF/jsp/io/input/configureImportData.jsp ===================================== --- a/t3-web/src/main/webapp/WEB-INF/jsp/io/input/configureImportData.jsp +++ b/t3-web/src/main/webapp/WEB-INF/jsp/io/input/configureImportData.jsp @@ -25,41 +25,47 @@ <script type="text/javascript"> - jQuery(document).ready(function () { - - function changeCanCreateVessel(val) { - var container = $('[name="createVirtualVessel"]'); - if (val) { - container.attr('disabled', false); - container.prop('checked', true); - } else { - container.attr('disabled', true); - } - } - - $('[name="canCreateVessel"]').change(function () { - changeCanCreateVessel($(this).prop('checked')); + jQuery(document).ready(function () { + function changeCanCreateVessel(val) { + var container = $('[name="createVirtualVessel"]'); + if (val) { + container.attr('disabled', false); + container.prop('checked', true); + } else { + container.attr('disabled', true); + } + } + function changeUseSamplesOnly(val) { + var container = $('[name="canCreateVirtualActivity"]'); + if (val) { + container.attr('disabled', false); + container.prop('checked', true); + } else { + container.attr('disabled', true); + container.attr('checked', true); + } + } + + $('[name="canCreateVessel"]').change(function () { + changeCanCreateVessel($(this).prop('checked')); + }); + $('[name="useSamplesOnly"]').change(function () { + changeUseSamplesOnly($(this).prop('checked')); + }); + changeCanCreateVessel(<s:property value="%{canCreateVessel}"/>); + changeUseSamplesOnly(<s:property value="%{useSamplesOnly}"/>); }); - - changeCanCreateVessel(<s:property value="%{canCreateVessel}"/>); - }); </script> <title><s:text name="t3.label.data.configureImportData"/></title> - <h2><s:text name="t3.label.data.configureImportData"/></h2> <s:form method="post" validate="true" enctype="multipart/form-data" namespace="/io"> - <s:hidden key="treatmentDirectoryPath" label=''/> - - <s:select key="inputProviderId" list="inputProviders" label='%{getText("t3.common.inputProvider")}' listKey="id" listValue="libelle" requiredLabel="true"/> - + <s:select key="inputProviderId" list="inputProviders" label='%{getText("t3.common.inputProvider")}' listKey="id" + listValue="libelle" requiredLabel="true"/> <s:if test="loadedSource==null"> - <s:hidden name="useWells" value="%{useWells}"/> - <s:file name="sourceToLoad" requiredLabel="true" label='%{getText("t3.common.sourceToUpload")} (*)'/> - <s:submit action="configureImportData!doAddSource" key="t3.action.importData.addSource" align="right"/> <br/> @@ -68,17 +74,14 @@ <s:param value="%{maxSize}"/> </s:text> </div> - </s:if> <s:else> - <s:hidden key="loadedSource" label=''/> - - <s:textfield value="%{loadedSource}" key="t3.common.uploaded.source" disabled="true" requiredLabel="true" size="40"/> - + <s:textfield value="%{loadedSource}" key="t3.common.uploaded.source" disabled="true" requiredLabel="true" + size="40"/> <s:checkbox key="useWells" label='%{getText("t3.common.force.useWells")}'/> - - <s:select key="tripType" list="tripTypes" label='%{getText("t3.common.tripType")}' requiredLabel="true"/> + <s:checkbox key="samplesOnly" label='%{getText("t3.common.useSamplesOnly")}'/> + <s:checkbox key="canCreateVirtualActivity" label='%{getText("t3.common.canCreateVirtualActivity")}'/> <s:checkbox key="canCreateVessel" label='%{getText("t3.common.canCreateVessel")}'/> <s:checkbox key="createVirtualVessel" label='%{getText("t3.common.createVirtualVessel")}'/> <s:submit action="configureImportData!doDeleteSource" key="t3.action.importData.deleteSource" align="right"/> ===================================== t3-web/src/main/webapp/WEB-INF/jsp/io/input/importDataConfigResume.jsp ===================================== --- a/t3-web/src/main/webapp/WEB-INF/jsp/io/input/importDataConfigResume.jsp +++ b/t3-web/src/main/webapp/WEB-INF/jsp/io/input/importDataConfigResume.jsp @@ -22,21 +22,23 @@ <%@ taglib prefix="s" uri="/struts-tags" %> <%@ taglib prefix="sj" uri="/struts-jquery-tags" %> <fieldset> - <legend> <s:text name="t3.label.importData.config.resume"/> </legend> - <s:form> - <s:select key="t3.common.inputProvider" list="inputProviders" listKey="id" listValue="libelle" value="%{configuration.inputProvider.id}" disabled="true"/> + <s:select key="t3.common.inputProvider" list="inputProviders" listKey="id" listValue="libelle" + value="%{configuration.inputProvider.id}" disabled="true"/> <s:textfield value="%{configuration.inputFile.name}" key="t3.common.uploaded.source" disabled="true" size="40"/> <s:label key="t3.common.useWells" value=""/> <s:checkbox name="useWells" value="%{configuration.useWells}" disabled="true" key="t3.common.force.useWells"/> - <s:select key="tripType" list="tripTypes" label='%{getText("t3.common.tripType")}' disabled="true" value="%{configuration.tripType}" /> - <s:checkbox name="canCreateVessel" value="%{configuration.canCreateVessel}" disabled="true" key="t3.common.canCreateVessel"/> + <s:checkbox name="samplesOnly" value="%{configuration.samplesOnly}" disabled="true" key="t3.common.samplesOnly"/> + <s:checkbox name="canCreateVirtualActivity" value="%{configuration.canCreateVirtualActivity}" disabled="true" + key="t3.common.canCreateVirtualActivity"/> + <s:checkbox name="canCreateVessel" value="%{configuration.canCreateVessel}" disabled="true" + key="t3.common.canCreateVessel"/> <s:if test="configuration.canCreateVessel"> - <s:checkbox name="createVirtualVessel" value="%{configuration.createVirtualVessel}" disabled="true" key="t3.common.createVirtualVessel"/> + <s:checkbox name="createVirtualVessel" value="%{configuration.createVirtualVessel}" disabled="true" + key="t3.common.createVirtualVessel"/> </s:if> </s:form> - </fieldset> View it on GitLab: https://gitlab.com/ultreiaio/ird-t3/commit/61b98792f5980af836d9efdac66bf2908... --- View it on GitLab: https://gitlab.com/ultreiaio/ird-t3/commit/61b98792f5980af836d9efdac66bf2908... You're receiving this email because of your account on gitlab.com.
participants (1)
-
Tony CHEMIT