package ch.epfl.cs107; import java.io.*; import java.nio.file.Files; import java.nio.file.Path; import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public final class Submit { private static final Path PROJECT_ROOT = Path.of(System.getProperty("user.dir")); private static final Path ICCOOP_PROJECT = PROJECT_ROOT.resolve("iccoop"); private static final Path TARGET_FOLDER = ICCOOP_PROJECT.resolve("target"); private static final Path SUBMISSION_FILE = TARGET_FOLDER.resolve("submission.zip"); private static final Path ICCOOP_RESOURCE_FOLDER = ICCOOP_PROJECT.resolve("src") .resolve("main") .resolve("resources"); /** ??? */ private static final Set<Path> DIRECTORIES_TO_IGNORE = Set.of( Path.of("out"), // output folder in Eclipse TARGET_FOLDER, Path.of(".idea"), Path.of("src", ".idea") ); // Les fichiers dont le nom commence par l'un de ces préfixes sont inclus dans le rendu. private static final Set<String> PREFIXES_TO_SUBMIT = Set.of("readme", "conception"); // Les fichiers dont le nom se termine par l'un de ces suffixes sont inclus dans le rendu. private static final Set<String> SUFFIXES_TO_SUBMIT = Set.of( ".java", ".png", ".ttf", ".wav", ".xml", ".txt", ".md", ".pdf" ); private static final Set<Path> RESOURCE_FILES_TO_IGNORE = Set.of( "fonts/Dragonfly.ttf", "fonts/OpenSans-Bold.ttf", "fonts/OpenSans-BoldItalic.ttf", "fonts/OpenSans-ExtraBold.ttf", "fonts/OpenSans-ExtraBoldItalic.ttf", "fonts/OpenSans-Italic.ttf", "fonts/OpenSans-Light.ttf", "fonts/OpenSans-LightItalic.ttf", "fonts/OpenSans-Regular.ttf", "fonts/OpenSans-Semibold.ttf", "fonts/OpenSans-SemiboldItalic.ttf" ).stream().map(ICCOOP_RESOURCE_FOLDER::resolve).collect(Collectors.toSet()); // ============================================================================================ // ========================================= MAIN ============================================= // ============================================================================================ public static void main(String[] args) { try { var root = ICCOOP_PROJECT.resolve("src").resolve("main"); Set<Path> pathsToIgnore = new HashSet<>(); pathsToIgnore.addAll(DIRECTORIES_TO_IGNORE); pathsToIgnore.addAll(RESOURCE_FILES_TO_IGNORE); var paths = filesToSubmit(root, path -> { var fileName = path.getFileName().toString().toLowerCase(); return pathsToIgnore.stream().noneMatch(path::startsWith) && !fileName.equals("submit.java") && (PREFIXES_TO_SUBMIT.stream().anyMatch(fileName::startsWith) || SUFFIXES_TO_SUBMIT.stream().anyMatch(fileName::endsWith)); }); var zipArchive = createZipArchive(ICCOOP_PROJECT.resolve("src"), paths); if(TARGET_FOLDER.toFile().mkdirs()) { System.out.printf("Dossier cible introuvable, création d’un nouveau à l’emplacement: %s.", TARGET_FOLDER); } Files.write(SUBMISSION_FILE, zipArchive); long archiveSizeBytes = Files.size(SUBMISSION_FILE); double archiveSizeKBs = archiveSizeBytes / Math.pow(2, 10); double archiveSizeMBs = archiveSizeBytes / Math.pow(2, 20); System.out.printf("Archive de soumission créée avec succès. Taille de l’archive: %.1f KB (%.2f MB).\n", archiveSizeKBs, archiveSizeMBs); System.out.printf("L’archive prête pour les soumissions a été créée à: %s.\n", SUBMISSION_FILE.toAbsolutePath()); } catch (IOException e) { System.err.println("Erreur inattendue !"); e.printStackTrace(System.err); System.exit(1); } } private static Set<Path> getFolderPathsToIgnore(Path baseFolder, Path pathIgnoreListFilePath) throws IOException { try(var lines = Files.lines(pathIgnoreListFilePath)) { return lines .filter(line -> !line.isBlank()) .map(baseFolder::resolve) .collect(Collectors.toSet()); } } private static List<Path> filesToSubmit(Path root, Predicate<Path> keepFile) throws IOException { try (var paths = Files.walk(root)) { return paths .filter(Files::isRegularFile) .filter(keepFile) .sorted(Comparator.comparing(Path::toString)) .toList(); } } private static byte[] createZipArchive(Path root, List<Path> paths) throws IOException { var byteArrayOutputStream = new ByteArrayOutputStream(); try (var zipStream = new ZipOutputStream(byteArrayOutputStream)) { for (var path : paths) { var relative = root.relativize(path); var entryPath = IntStream.range(0, relative.getNameCount()) .mapToObj(relative::getName) .map(Path::toString) .collect(Collectors.joining(File.separator, "", "")); zipStream.putNextEntry(new ZipEntry(entryPath)); try (var fileStream = new FileInputStream(path.toFile())) { fileStream.transferTo(zipStream); } zipStream.closeEntry(); } } return byteArrayOutputStream.toByteArray(); } }