diff --git a/README.md b/README.md index 87b1645a0d4238312094846bdb1800185f191b5e..865760750bfa37275f7eabf8912373237eb6357c 100644 --- a/README.md +++ b/README.md @@ -60,4 +60,3 @@ Puis ouvrir le fichier `target/site/apidocs/index.html` ### Fonctionnement ## Fonctionnalités - diff --git a/src/main/java/fil/sr2/flopbox/FTPResource.java b/src/main/java/fil/sr2/flopbox/FTPResource.java index c9220549fa41958c18b21c958f1c383b137818f7..7feae6d273be75fafc0b2228bdb5621e903ce107 100644 --- a/src/main/java/fil/sr2/flopbox/FTPResource.java +++ b/src/main/java/fil/sr2/flopbox/FTPResource.java @@ -27,8 +27,11 @@ public class FTPResource { return Response.ok(servers).build(); } + // returns the content of the directory as an array it is a directory OR the + // content of the file @GET @Path("/{alias}/{path: .+}") + @Produces(MediaType.APPLICATION_JSON) public Response getFTPResource( @PathParam("alias") String alias, @PathParam("path") String path, @@ -44,7 +47,6 @@ public class FTPResource { FTPClient ftpClient = new FTPClient(); try { - // Connexion et authentification FTP ftpClient.connect(config.getHost(), config.getPort()); if (!ftpClient.login(user, pass)) { return Response.status(Response.Status.UNAUTHORIZED) @@ -53,38 +55,64 @@ public class FTPResource { ftpClient.enterLocalPassiveMode(); ftpClient.setFileType(FTP.BINARY_FILE_TYPE); - // Vérifier l'existence et le type de la ressource + // Normaliser le chemin en retirant le slash final + if (path.endsWith("/")) { + path = path.substring(0, path.length() - 1); + } + + // Vérifier si le chemin est un répertoire FTPFile[] files = ftpClient.listFiles(path); if (files == null || files.length == 0) { return Response.status(Response.Status.NOT_FOUND) .entity("Ressource non trouvée : " + path).build(); } - FTPFile file = files[0]; - if (file.isDirectory()) { - // Si c'est un répertoire, renvoyer la liste des noms de fichiers/répertoires - String[] names = ftpClient.listNames(path); - ftpClient.logout(); - ftpClient.disconnect(); - return Response.ok(names).build(); - } else { - // Si c'est un fichier, renvoyer un flux binaire pour le téléchargement - InputStream is = ftpClient.retrieveFileStream(path); - if (is == null) { - return Response.status(Response.Status.INTERNAL_SERVER_ERROR) - .entity("Échec de la récupération du fichier").build(); - } - // On utilise ici une classe utilitaire pour fermer proprement le flux et la - // connexion FTP - return Response.ok(new InputStreamResource(is, ftpClient)) - .header("Content-Disposition", "attachment; filename=\"" + getFileName(path) + "\"") - .build(); - } + + // Construire la structure JSON + FtpNode root = buildFtpTree(ftpClient, path); + ftpClient.logout(); + ftpClient.disconnect(); + + return Response.ok(root).build(); + } catch (IOException e) { return Response.status(Response.Status.INTERNAL_SERVER_ERROR) .entity("Erreur FTP : " + e.getMessage()).build(); } } + // Fonction récursive pour construire l'arborescence FTP + private FtpNode buildFtpTree(FTPClient ftpClient, String path) throws IOException { + FTPFile[] files = ftpClient.listFiles(path); + FtpNode node = new FtpNode(getFileName(path), true); // Root est un dossier + + if (files != null) { + for (FTPFile file : files) { + String fullPath = path + "/" + file.getName(); + if (file.isDirectory()) { + node.children.add(buildFtpTree(ftpClient, fullPath)); // Récursif pour les dossiers + } else { + node.children.add(new FtpNode(file.getName(), false)); // Ajouter fichier + } + } + } + return node; + } + + // Classe représentant un nœud JSON (fichier ou dossier) + static class FtpNode { + public String name; + public boolean isDirectory; + public List<FtpNode> children; + + public FtpNode(String name, boolean isDirectory) { + this.name = name; + this.isDirectory = isDirectory; + if (isDirectory) { + this.children = new java.util.ArrayList<>(); + } + } + } + // POST /ftps - enregistre un nouveau serveur FTP @POST @Consumes(MediaType.APPLICATION_JSON)