diff --git a/src/main/java/org/qortal/arbitrary/misc/Service.java b/src/main/java/org/qortal/arbitrary/misc/Service.java index 981aa119..5dd8d94e 100644 --- a/src/main/java/org/qortal/arbitrary/misc/Service.java +++ b/src/main/java/org/qortal/arbitrary/misc/Service.java @@ -1,16 +1,18 @@ package org.qortal.arbitrary.misc; +import org.apache.commons.io.FilenameUtils; import org.json.JSONObject; import org.qortal.arbitrary.ArbitraryDataRenderer; import org.qortal.transaction.Transaction; import org.qortal.utils.FilesystemUtils; +import java.io.File; import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.Objects; import static java.util.Arrays.stream; import static java.util.stream.Collectors.toMap; @@ -48,7 +50,31 @@ public enum Service { LIST(900, true, null, null), PLAYLIST(910, true, null, null), APP(1000, false, null, null), - METADATA(1100, false, null, null); + METADATA(1100, false, null, null), + GIF_REPOSITORY(1200, true, 25*1024*1024L, null) { + @Override + public ValidationResult validate(Path path) { + // Custom validation function to require .gif files only, and at least 1 + int gifCount = 0; + File[] files = path.toFile().listFiles(); + if (files != null) { + for (File file : files) { + if (file.isDirectory()) { + return ValidationResult.DIRECTORIES_NOT_ALLOWED; + } + String extension = FilenameUtils.getExtension(file.getName()).toLowerCase(); + if (!Objects.equals(extension, "gif")) { + return ValidationResult.INVALID_FILE_EXTENSION; + } + gifCount++; + } + } + if (gifCount == 0) { + return ValidationResult.MISSING_DATA; + } + return ValidationResult.OK; + } + }; public final int value; private final boolean requiresValidation; @@ -114,7 +140,10 @@ public enum Service { OK(1), MISSING_KEYS(2), EXCEEDS_SIZE_LIMIT(3), - MISSING_INDEX_FILE(4); + MISSING_INDEX_FILE(4), + DIRECTORIES_NOT_ALLOWED(5), + INVALID_FILE_EXTENSION(6), + MISSING_DATA(7); public final int value; diff --git a/src/test/java/org/qortal/test/arbitrary/ArbitraryServiceTests.java b/src/test/java/org/qortal/test/arbitrary/ArbitraryServiceTests.java index d71910f7..e6a51776 100644 --- a/src/test/java/org/qortal/test/arbitrary/ArbitraryServiceTests.java +++ b/src/test/java/org/qortal/test/arbitrary/ArbitraryServiceTests.java @@ -101,4 +101,78 @@ public class ArbitraryServiceTests extends Common { assertEquals(ValidationResult.MISSING_INDEX_FILE, service.validate(path)); } + @Test + public void testValidateGifRepository() throws IOException { + // Generate some random data + byte[] data = new byte[1024]; + new Random().nextBytes(data); + + // Write the data to several files in a temp path + Path path = Files.createTempDirectory("testValidateGifRepository"); + path.toFile().deleteOnExit(); + Files.write(Paths.get(path.toString(), "image1.gif"), data, StandardOpenOption.CREATE); + Files.write(Paths.get(path.toString(), "image2.gif"), data, StandardOpenOption.CREATE); + Files.write(Paths.get(path.toString(), "image3.gif"), data, StandardOpenOption.CREATE); + + Service service = Service.GIF_REPOSITORY; + assertTrue(service.isValidationRequired()); + + // There is an index file in the root + assertEquals(ValidationResult.OK, service.validate(path)); + } + + @Test + public void testValidateMultiLayerGifRepository() throws IOException { + // Generate some random data + byte[] data = new byte[1024]; + new Random().nextBytes(data); + + // Write the data to several files in a temp path + Path path = Files.createTempDirectory("testValidateMultiLayerGifRepository"); + path.toFile().deleteOnExit(); + Files.write(Paths.get(path.toString(), "image1.gif"), data, StandardOpenOption.CREATE); + + Path subdirectory = Paths.get(path.toString(), "subdirectory"); + Files.createDirectories(subdirectory); + Files.write(Paths.get(subdirectory.toString(), "image2.gif"), data, StandardOpenOption.CREATE); + Files.write(Paths.get(subdirectory.toString(), "image3.gif"), data, StandardOpenOption.CREATE); + + Service service = Service.GIF_REPOSITORY; + assertTrue(service.isValidationRequired()); + + // There is an index file in the root + assertEquals(ValidationResult.DIRECTORIES_NOT_ALLOWED, service.validate(path)); + } + + @Test + public void testValidateEmptyGifRepository() throws IOException { + Path path = Files.createTempDirectory("testValidateEmptyGifRepository"); + + Service service = Service.GIF_REPOSITORY; + assertTrue(service.isValidationRequired()); + + // There is an index file in the root + assertEquals(ValidationResult.MISSING_DATA, service.validate(path)); + } + + @Test + public void testValidateInvalidGifRepository() throws IOException { + // Generate some random data + byte[] data = new byte[1024]; + new Random().nextBytes(data); + + // Write the data to several files in a temp path + Path path = Files.createTempDirectory("testValidateInvalidGifRepository"); + path.toFile().deleteOnExit(); + Files.write(Paths.get(path.toString(), "image1.gif"), data, StandardOpenOption.CREATE); + Files.write(Paths.get(path.toString(), "image2.gif"), data, StandardOpenOption.CREATE); + Files.write(Paths.get(path.toString(), "image3.jpg"), data, StandardOpenOption.CREATE); // Invalid extension + + Service service = Service.GIF_REPOSITORY; + assertTrue(service.isValidationRequired()); + + // There is an index file in the root + assertEquals(ValidationResult.INVALID_FILE_EXTENSION, service.validate(path)); + } + }