233 lines
8.8 KiB
Java
233 lines
8.8 KiB
Java
package fr.titionfire.ffsaf.domain.service;
|
|
|
|
import fr.titionfire.ffsaf.data.model.ClubModel;
|
|
import fr.titionfire.ffsaf.data.model.LicenceModel;
|
|
import fr.titionfire.ffsaf.data.model.MembreModel;
|
|
import fr.titionfire.ffsaf.data.repository.ClubRepository;
|
|
import fr.titionfire.ffsaf.data.repository.CombRepository;
|
|
import fr.titionfire.ffsaf.rest.exception.DNotFoundException;
|
|
import fr.titionfire.ffsaf.utils.Utils;
|
|
import io.quarkus.hibernate.reactive.panache.common.WithSession;
|
|
import io.smallrye.mutiny.Uni;
|
|
import io.smallrye.mutiny.unchecked.Unchecked;
|
|
import jakarta.enterprise.context.ApplicationScoped;
|
|
import jakarta.inject.Inject;
|
|
import jakarta.ws.rs.core.HttpHeaders;
|
|
import jakarta.ws.rs.core.MediaType;
|
|
import jakarta.ws.rs.core.Response;
|
|
import org.eclipse.microprofile.config.inject.ConfigProperty;
|
|
import org.hibernate.reactive.mutiny.Mutiny;
|
|
import org.jboss.logging.Logger;
|
|
|
|
import java.io.*;
|
|
import java.text.SimpleDateFormat;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.UUID;
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
@WithSession
|
|
@ApplicationScoped
|
|
public class PDFService {
|
|
private static final Logger LOGGER = Logger.getLogger(PDFService.class);
|
|
|
|
@Inject
|
|
CombRepository combRepository;
|
|
|
|
@Inject
|
|
ClubRepository clubRepository;
|
|
|
|
@ConfigProperty(name = "upload_dir")
|
|
String media;
|
|
|
|
@ConfigProperty(name = "pdf-maker.jar-path")
|
|
String pdfMakerJarPath;
|
|
|
|
@ConfigProperty(name = "pdf-maker.sign-file")
|
|
String sign_file;
|
|
|
|
|
|
public Uni<Response> getLicencePdf(String subject) {
|
|
return getLicencePdf(combRepository.find("userId = ?1", subject).firstResult()
|
|
.call(m -> Mutiny.fetch(m.getLicences())));
|
|
}
|
|
|
|
public Uni<Response> getLicencePdf(Uni<MembreModel> uniBase) {
|
|
return uniBase
|
|
.map(Unchecked.function(m -> {
|
|
LicenceModel licence = m.getLicences().stream()
|
|
.filter(licenceModel -> licenceModel.getSaison() == Utils.getSaison() && licenceModel.isValidate())
|
|
.findFirst()
|
|
.orElseThrow(() -> new DNotFoundException("Pas de licence pour la saison en cours"));
|
|
|
|
try {
|
|
byte[] buff = make_pdf(m, licence);
|
|
if (buff == null)
|
|
throw new IOException("Error making pdf");
|
|
|
|
String mimeType = "application/pdf";
|
|
|
|
Response.ResponseBuilder resp = Response.ok(buff);
|
|
resp.type(MediaType.APPLICATION_OCTET_STREAM);
|
|
resp.header(HttpHeaders.CONTENT_LENGTH, buff.length);
|
|
resp.header(HttpHeaders.CONTENT_TYPE, mimeType);
|
|
resp.header(HttpHeaders.CONTENT_DISPOSITION,
|
|
"inline; " + "filename=\"Attestation d'adhésion " + Utils.getSaison() + "-" +
|
|
(Utils.getSaison() + 1) + " de " + m.getLname() + " " + m.getFname() + ".pdf\"");
|
|
return resp.build();
|
|
} catch (Exception e) {
|
|
throw new IOException(e);
|
|
}
|
|
}));
|
|
}
|
|
|
|
private byte[] make_pdf(MembreModel m, LicenceModel licence) throws IOException, InterruptedException {
|
|
List<String> cmd = new ArrayList<>();
|
|
cmd.add("java");
|
|
cmd.add("-jar");
|
|
cmd.add(pdfMakerJarPath);
|
|
|
|
UUID uuid = UUID.randomUUID();
|
|
|
|
cmd.add("/tmp/" + uuid + ".pdf");
|
|
cmd.add("membre");
|
|
cmd.add(m.getFname());
|
|
cmd.add(m.getLname());
|
|
cmd.add(m.getGenre().str);
|
|
cmd.add(m.getCategorie().getName());
|
|
cmd.add(licence.getCertificate() == null ? "" : licence.getCertificate());
|
|
cmd.add(Utils.getSaison() + "");
|
|
cmd.add(m.getLicence() + "");
|
|
cmd.add(m.getClub().getName());
|
|
cmd.add(m.getClub().getNo_affiliation() + "");
|
|
cmd.add(m.getBirth_date() == null ? "--" : new SimpleDateFormat("dd/MM/yyyy").format(m.getBirth_date()));
|
|
|
|
FilenameFilter filter = (directory, filename) -> filename.startsWith(m.getId() + ".");
|
|
File[] files = new File(media, "ppMembre").listFiles(filter);
|
|
if (files != null && files.length > 0) {
|
|
File file = files[0];
|
|
cmd.add(file.getAbsolutePath());
|
|
} else {
|
|
cmd.add("/dev/null");
|
|
}
|
|
|
|
return getPdf(cmd, uuid);
|
|
}
|
|
|
|
public Uni<Response> getAffiliationPdf(String subject) {
|
|
return getAffiliationPdf(
|
|
combRepository.find("userId = ?1", subject).firstResult()
|
|
.invoke(Unchecked.consumer(m -> {
|
|
if (m == null || m.getClub() == null)
|
|
throw new DNotFoundException("Club non trouvé");
|
|
}))
|
|
.map(MembreModel::getClub)
|
|
.call(m -> Mutiny.fetch(m.getAffiliations())));
|
|
}
|
|
|
|
public Uni<Response> getAffiliationPdf(long id) {
|
|
return getAffiliationPdf(
|
|
clubRepository.findById(id)
|
|
.invoke(Unchecked.consumer(m -> {
|
|
if (m == null)
|
|
throw new DNotFoundException("Club non trouvé");
|
|
}))
|
|
.call(m -> Mutiny.fetch(m.getAffiliations())));
|
|
}
|
|
|
|
|
|
private Uni<Response> getAffiliationPdf(Uni<ClubModel> uniBase) {
|
|
return uniBase
|
|
.map(Unchecked.function(m -> {
|
|
if (m.getAffiliations().stream()
|
|
.noneMatch(licenceModel -> licenceModel.getSaison() == Utils.getSaison()))
|
|
throw new DNotFoundException("Pas d'affiliation pour la saison en cours");
|
|
|
|
try {
|
|
byte[] buff = make_pdf(m);
|
|
if (buff == null)
|
|
throw new IOException("Error making pdf");
|
|
|
|
String mimeType = "application/pdf";
|
|
|
|
Response.ResponseBuilder resp = Response.ok(buff);
|
|
resp.type(MediaType.APPLICATION_OCTET_STREAM);
|
|
resp.header(HttpHeaders.CONTENT_LENGTH, buff.length);
|
|
resp.header(HttpHeaders.CONTENT_TYPE, mimeType);
|
|
resp.header(HttpHeaders.CONTENT_DISPOSITION,
|
|
"inline; " + "filename=\"Attestation d'affiliation " + Utils.getSaison() + "-" +
|
|
(Utils.getSaison() + 1) + " de " + m.getName() + ".pdf\"");
|
|
return resp.build();
|
|
} catch (Exception e) {
|
|
throw new IOException(e);
|
|
}
|
|
}));
|
|
}
|
|
|
|
private byte[] make_pdf(ClubModel m) throws IOException, InterruptedException {
|
|
List<String> cmd = new ArrayList<>();
|
|
cmd.add("java");
|
|
cmd.add("-jar");
|
|
cmd.add(pdfMakerJarPath);
|
|
|
|
UUID uuid = UUID.randomUUID();
|
|
|
|
cmd.add("/tmp/" + uuid + ".pdf");
|
|
cmd.add("club");
|
|
cmd.add(m.getName());
|
|
cmd.add(Utils.getSaison() + "");
|
|
cmd.add(m.getNo_affiliation() + "");
|
|
cmd.add(new File(sign_file).getAbsolutePath());
|
|
|
|
return getPdf(cmd, uuid);
|
|
}
|
|
|
|
static byte[] getPdf(List<String> cmd, UUID uuid) throws IOException, InterruptedException {
|
|
ProcessBuilder processBuilder = new ProcessBuilder(cmd);
|
|
processBuilder.redirectErrorStream(true);
|
|
Process process = processBuilder.start();
|
|
|
|
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
|
|
|
StringBuilder builder = new StringBuilder();
|
|
Thread t = new Thread(() -> {
|
|
try {
|
|
String line;
|
|
while ((line = reader.readLine()) != null)
|
|
builder.append(line).append("\n");
|
|
} catch (Exception ignored) {
|
|
}
|
|
});
|
|
t.start();
|
|
|
|
int code = -1;
|
|
if (!process.waitFor(30, TimeUnit.SECONDS)) {
|
|
process.destroy();
|
|
builder.append("Timeout...");
|
|
} else {
|
|
code = process.exitValue();
|
|
}
|
|
|
|
if (t.isAlive())
|
|
t.interrupt();
|
|
|
|
PDFService.LOGGER.debug("PDF maker: " + builder);
|
|
|
|
if (code != 0) {
|
|
throw new IOException("Error code: " + code);
|
|
} else {
|
|
File file = new File("/tmp/" + uuid + ".pdf");
|
|
try (FileInputStream fis = new FileInputStream(file)) {
|
|
byte[] buff = fis.readAllBytes();
|
|
//noinspection ResultOfMethodCallIgnored
|
|
file.delete();
|
|
return buff;
|
|
} catch (IOException e) {
|
|
//noinspection ResultOfMethodCallIgnored
|
|
file.delete();
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
}
|