235 lines
7.6 KiB
Java
235 lines
7.6 KiB
Java
package com.lions.dev.resource;
|
|
|
|
import com.lions.dev.service.FileService;
|
|
import jakarta.ws.rs.Consumes;
|
|
import jakarta.ws.rs.GET;
|
|
import jakarta.ws.rs.POST;
|
|
import jakarta.ws.rs.Path;
|
|
import jakarta.ws.rs.PathParam;
|
|
import jakarta.ws.rs.Produces;
|
|
import jakarta.ws.rs.core.Context;
|
|
import jakarta.ws.rs.core.MediaType;
|
|
import jakarta.ws.rs.core.Response;
|
|
import jakarta.ws.rs.core.UriInfo;
|
|
import org.jboss.logging.Logger;
|
|
import org.jboss.resteasy.reactive.RestForm;
|
|
import org.jboss.resteasy.reactive.multipart.FileUpload;
|
|
import jakarta.inject.Inject;
|
|
import java.io.IOException;
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
import java.util.UUID;
|
|
|
|
@Path("/media")
|
|
public class FileUploadResource {
|
|
|
|
private static final Logger LOG = Logger.getLogger(FileUploadResource.class);
|
|
|
|
@Inject
|
|
FileService fileService;
|
|
|
|
@Context
|
|
UriInfo uriInfo;
|
|
|
|
@POST
|
|
@Path("/upload")
|
|
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
|
@Produces(MediaType.APPLICATION_JSON)
|
|
public Response uploadFile(
|
|
@RestForm("file") FileUpload file,
|
|
@RestForm("type") String type,
|
|
@RestForm("fileName") String fileName,
|
|
@RestForm("contentType") String contentType,
|
|
@RestForm("fileSize") String fileSize,
|
|
@RestForm("userId") String userId) {
|
|
|
|
LOG.info("Début de l'upload de fichier");
|
|
LOG.infof("Type: %s, FileName: %s, ContentType: %s, FileSize: %s, UserId: %s",
|
|
type, fileName, contentType, fileSize, userId);
|
|
|
|
if (file == null || file.uploadedFile() == null) {
|
|
LOG.error("Aucun fichier fourni dans la requête");
|
|
return Response.status(Response.Status.BAD_REQUEST)
|
|
.entity(createErrorResponse("Aucun fichier fourni"))
|
|
.build();
|
|
}
|
|
|
|
try {
|
|
// Générer un nom de fichier unique si nécessaire
|
|
String finalFileName = fileName != null && !fileName.isEmpty()
|
|
? fileName
|
|
: generateUniqueFileName(file.fileName());
|
|
|
|
// Déterminer le type de média
|
|
String mediaType = type != null && !type.isEmpty()
|
|
? type
|
|
: determineMediaType(file.fileName());
|
|
|
|
// Répertoire d'upload
|
|
String uploadDir = "/tmp/uploads/";
|
|
|
|
// Sauvegarder le fichier
|
|
java.nio.file.Path savedFilePath = fileService.saveFile(
|
|
file.uploadedFile(),
|
|
uploadDir,
|
|
finalFileName
|
|
);
|
|
|
|
LOG.infof("Fichier sauvegardé avec succès: %s", savedFilePath);
|
|
|
|
// Construire l'URL du fichier
|
|
// Note: En production, vous devriez utiliser une URL publique (CDN, S3, etc.)
|
|
String fileUrl = buildFileUrl(finalFileName, uriInfo);
|
|
String thumbnailUrl = null;
|
|
|
|
// Pour les vidéos, on pourrait générer un thumbnail ici
|
|
if ("video".equalsIgnoreCase(mediaType)) {
|
|
// TODO: Générer un thumbnail pour les vidéos
|
|
thumbnailUrl = fileUrl; // Placeholder
|
|
}
|
|
|
|
// Construire la réponse JSON
|
|
Map<String, Object> response = new HashMap<>();
|
|
response.put("url", fileUrl);
|
|
if (thumbnailUrl != null) {
|
|
response.put("thumbnailUrl", thumbnailUrl);
|
|
}
|
|
response.put("type", mediaType);
|
|
if (fileSize != null && !fileSize.isEmpty()) {
|
|
try {
|
|
long size = Long.parseLong(fileSize);
|
|
// Pour les vidéos, on pourrait calculer la durée ici
|
|
// response.put("duration", durationInSeconds);
|
|
} catch (NumberFormatException e) {
|
|
LOG.warnf("Impossible de parser fileSize: %s", fileSize);
|
|
}
|
|
}
|
|
|
|
LOG.infof("Upload réussi, URL: %s", fileUrl);
|
|
|
|
return Response.status(Response.Status.CREATED)
|
|
.entity(response)
|
|
.build();
|
|
|
|
} catch (IOException e) {
|
|
LOG.errorf(e, "Erreur lors de l'upload du fichier: %s", e.getMessage());
|
|
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
|
.entity(createErrorResponse("Erreur lors de l'upload du fichier: " + e.getMessage()))
|
|
.build();
|
|
} catch (Exception e) {
|
|
LOG.errorf(e, "Erreur inattendue lors de l'upload: %s", e.getMessage());
|
|
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
|
.entity(createErrorResponse("Erreur inattendue."))
|
|
.build();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Génère un nom de fichier unique.
|
|
*/
|
|
private String generateUniqueFileName(String originalFileName) {
|
|
String extension = "";
|
|
int lastDot = originalFileName.lastIndexOf('.');
|
|
if (lastDot > 0) {
|
|
extension = originalFileName.substring(lastDot);
|
|
}
|
|
return UUID.randomUUID().toString() + extension;
|
|
}
|
|
|
|
/**
|
|
* Détermine le type de média basé sur l'extension du fichier.
|
|
*/
|
|
private String determineMediaType(String fileName) {
|
|
if (fileName == null) {
|
|
return "image";
|
|
}
|
|
String lowerFileName = fileName.toLowerCase();
|
|
if (lowerFileName.endsWith(".mp4") ||
|
|
lowerFileName.endsWith(".mov") ||
|
|
lowerFileName.endsWith(".avi") ||
|
|
lowerFileName.endsWith(".mkv") ||
|
|
lowerFileName.endsWith(".m4v")) {
|
|
return "video";
|
|
}
|
|
return "image";
|
|
}
|
|
|
|
/**
|
|
* Construit l'URL du fichier.
|
|
* En production, cela devrait pointer vers un CDN ou un service de stockage.
|
|
*/
|
|
private String buildFileUrl(String fileName, UriInfo uriInfo) {
|
|
// Construire l'URL de base à partir de l'URI de la requête
|
|
String baseUri = uriInfo.getBaseUri().toString();
|
|
// Retirer le slash final s'il existe
|
|
if (baseUri.endsWith("/")) {
|
|
baseUri = baseUri.substring(0, baseUri.length() - 1);
|
|
}
|
|
// Retourner une URL absolue
|
|
return baseUri + "/media/files/" + fileName;
|
|
}
|
|
|
|
@GET
|
|
@Path("/files/{fileName}")
|
|
@Produces(MediaType.APPLICATION_OCTET_STREAM)
|
|
public Response getFile(@PathParam("fileName") String fileName) {
|
|
try {
|
|
java.nio.file.Path filePath = java.nio.file.Paths.get("/tmp/uploads/", fileName);
|
|
|
|
if (!java.nio.file.Files.exists(filePath)) {
|
|
LOG.warnf("Fichier non trouvé: %s", fileName);
|
|
return Response.status(Response.Status.NOT_FOUND)
|
|
.entity(createErrorResponse("Fichier non trouvé"))
|
|
.build();
|
|
}
|
|
|
|
// Déterminer le content-type
|
|
String contentType = determineContentType(fileName);
|
|
|
|
return Response.ok(filePath.toFile())
|
|
.type(contentType)
|
|
.header("Content-Disposition", "inline; filename=\"" + fileName + "\"")
|
|
.build();
|
|
|
|
} catch (Exception e) {
|
|
LOG.errorf(e, "Erreur lors de la récupération du fichier: %s", fileName);
|
|
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
|
.entity(createErrorResponse("Erreur lors de la récupération du fichier"))
|
|
.build();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Détermine le content-type basé sur l'extension du fichier.
|
|
*/
|
|
private String determineContentType(String fileName) {
|
|
if (fileName == null) {
|
|
return MediaType.APPLICATION_OCTET_STREAM;
|
|
}
|
|
String lowerFileName = fileName.toLowerCase();
|
|
if (lowerFileName.endsWith(".jpg") || lowerFileName.endsWith(".jpeg")) {
|
|
return "image/jpeg";
|
|
} else if (lowerFileName.endsWith(".png")) {
|
|
return "image/png";
|
|
} else if (lowerFileName.endsWith(".gif")) {
|
|
return "image/gif";
|
|
} else if (lowerFileName.endsWith(".mp4")) {
|
|
return "video/mp4";
|
|
} else if (lowerFileName.endsWith(".mov")) {
|
|
return "video/quicktime";
|
|
} else if (lowerFileName.endsWith(".avi")) {
|
|
return "video/x-msvideo";
|
|
}
|
|
return MediaType.APPLICATION_OCTET_STREAM;
|
|
}
|
|
|
|
/**
|
|
* Crée une réponse d'erreur JSON.
|
|
*/
|
|
private Map<String, String> createErrorResponse(String message) {
|
|
Map<String, String> error = new HashMap<>();
|
|
error.put("error", message);
|
|
return error;
|
|
}
|
|
}
|