diff --git a/code/common/db/src/main/java/nu/marginalia/db/storage/FileStorageService.java b/code/common/db/src/main/java/nu/marginalia/db/storage/FileStorageService.java index 2a22cbd2..9f0be634 100644 --- a/code/common/db/src/main/java/nu/marginalia/db/storage/FileStorageService.java +++ b/code/common/db/src/main/java/nu/marginalia/db/storage/FileStorageService.java @@ -13,6 +13,7 @@ import java.io.IOException; import java.nio.file.*; import java.nio.file.attribute.PosixFilePermissions; import java.sql.SQLException; +import java.time.LocalDateTime; import java.util.*; /** Manages file storage for processes and services @@ -292,6 +293,7 @@ public class FileStorageService { new FileStorageId(rs.getLong("ID")), base, type, + LocalDateTime.now(), newDir.toString(), description ); @@ -305,7 +307,7 @@ public class FileStorageService { public FileStorage getStorageByType(FileStorageType type) throws SQLException { try (var conn = dataSource.getConnection(); var stmt = conn.prepareStatement(""" - SELECT PATH, DESCRIPTION, ID, BASE_ID + SELECT PATH, DESCRIPTION, ID, BASE_ID, CREATE_DATE FROM FILE_STORAGE_VIEW WHERE TYPE = ? """)) { stmt.setString(1, type.name()); @@ -314,11 +316,13 @@ public class FileStorageService { long baseId; String path; String description; + LocalDateTime createDateTime; try (var rs = stmt.executeQuery()) { if (rs.next()) { baseId = rs.getLong("BASE_ID"); storageId = rs.getLong("ID"); + createDateTime = rs.getTimestamp("CREATE_DATE").toLocalDateTime(); path = rs.getString("PATH"); description = rs.getString("DESCRIPTION"); } @@ -332,6 +336,7 @@ public class FileStorageService { new FileStorageId(storageId), base, type, + createDateTime, path, description ); @@ -344,7 +349,7 @@ public class FileStorageService { try (var conn = dataSource.getConnection(); var stmt = conn.prepareStatement(""" - SELECT PATH, TYPE, DESCRIPTION, ID, BASE_ID + SELECT PATH, TYPE, DESCRIPTION, CREATE_DATE, ID, BASE_ID FROM FILE_STORAGE_VIEW WHERE ID = ? """)) { stmt.setLong(1, id.id()); @@ -354,6 +359,7 @@ public class FileStorageService { String path; String description; FileStorageType type; + LocalDateTime createDateTime; try (var rs = stmt.executeQuery()) { if (rs.next()) { @@ -362,6 +368,7 @@ public class FileStorageService { type = FileStorageType.valueOf(rs.getString("TYPE")); path = rs.getString("PATH"); description = rs.getString("DESCRIPTION"); + createDateTime = rs.getTimestamp("CREATE_DATE").toLocalDateTime(); } else { return null; @@ -373,6 +380,7 @@ public class FileStorageService { new FileStorageId(storageId), base, type, + createDateTime, path, description ); @@ -394,7 +402,7 @@ public class FileStorageService { List ret = new ArrayList<>(); try (var conn = dataSource.getConnection(); var stmt = conn.prepareStatement(""" - SELECT PATH, TYPE, DESCRIPTION, ID, BASE_ID + SELECT PATH, TYPE, DESCRIPTION, CREATE_DATE, ID, BASE_ID FROM FILE_STORAGE_VIEW """)) { @@ -402,6 +410,7 @@ public class FileStorageService { long baseId; String path; String description; + LocalDateTime createDateTime; FileStorageType type; try (var rs = stmt.executeQuery()) { @@ -411,13 +420,14 @@ public class FileStorageService { path = rs.getString("PATH"); type = FileStorageType.valueOf(rs.getString("TYPE")); description = rs.getString("DESCRIPTION"); - + createDateTime = rs.getTimestamp("CREATE_DATE").toLocalDateTime(); var base = getStorageBase(new FileStorageBaseId(baseId)); ret.add(new FileStorage( new FileStorageId(storageId), base, type, + createDateTime, path, description )); diff --git a/code/common/db/src/main/java/nu/marginalia/db/storage/model/FileStorage.java b/code/common/db/src/main/java/nu/marginalia/db/storage/model/FileStorage.java index 3a619809..25479f67 100644 --- a/code/common/db/src/main/java/nu/marginalia/db/storage/model/FileStorage.java +++ b/code/common/db/src/main/java/nu/marginalia/db/storage/model/FileStorage.java @@ -1,6 +1,8 @@ package nu.marginalia.db.storage.model; import java.nio.file.Path; +import java.time.LocalDateTime; +import java.util.Objects; /** * Represents a file storage area @@ -15,10 +17,38 @@ public record FileStorage( FileStorageId id, FileStorageBase base, FileStorageType type, + LocalDateTime createDateTime, String path, String description) { public Path asPath() { return Path.of(path); } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + FileStorage that = (FileStorage) o; + + // Exclude timestamp as it may different due to how the objects + // are constructed + + if (!Objects.equals(id, that.id)) return false; + if (!Objects.equals(base, that.base)) return false; + if (type != that.type) return false; + if (!Objects.equals(path, that.path)) return false; + return Objects.equals(description, that.description); + } + + @Override + public int hashCode() { + int result = id != null ? id.hashCode() : 0; + result = 31 * result + (base != null ? base.hashCode() : 0); + result = 31 * result + (type != null ? type.hashCode() : 0); + result = 31 * result + (path != null ? path.hashCode() : 0); + result = 31 * result + (description != null ? description.hashCode() : 0); + return result; + } } diff --git a/code/processes/loading-process/src/test/java/nu/marginalia/loading/loader/LoaderIndexJournalWriterTest.java b/code/processes/loading-process/src/test/java/nu/marginalia/loading/loader/LoaderIndexJournalWriterTest.java index f6958431..44b55476 100644 --- a/code/processes/loading-process/src/test/java/nu/marginalia/loading/loader/LoaderIndexJournalWriterTest.java +++ b/code/processes/loading-process/src/test/java/nu/marginalia/loading/loader/LoaderIndexJournalWriterTest.java @@ -31,7 +31,7 @@ class LoaderIndexJournalWriterTest { tempDir = Files.createTempDirectory(getClass().getSimpleName()); FileStorageService storageService = Mockito.mock(FileStorageService.class); Mockito.when(storageService.getStorageByType(FileStorageType.INDEX_STAGING)). - thenReturn(new FileStorage(null, null, null, tempDir.toString(), + thenReturn(new FileStorage(null, null, null, null, tempDir.toString(), "test")); writer = new LoaderIndexJournalWriter(storageService); } diff --git a/code/services-core/control-service/src/main/java/nu/marginalia/control/model/FileStorageWithActions.java b/code/services-core/control-service/src/main/java/nu/marginalia/control/model/FileStorageWithActions.java index d77d28f2..0cf1a399 100644 --- a/code/services-core/control-service/src/main/java/nu/marginalia/control/model/FileStorageWithActions.java +++ b/code/services-core/control-service/src/main/java/nu/marginalia/control/model/FileStorageWithActions.java @@ -4,6 +4,10 @@ import nu.marginalia.db.storage.model.FileStorage; import nu.marginalia.db.storage.model.FileStorageBaseType; import nu.marginalia.db.storage.model.FileStorageType; +import java.nio.file.Path; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; + public record FileStorageWithActions(FileStorage storage) { public boolean isCrawlable() { return storage.type() == FileStorageType.CRAWL_SPEC; @@ -27,4 +31,27 @@ public record FileStorageWithActions(FileStorage storage) { return baseType == FileStorageBaseType.SLOW || baseType == FileStorageBaseType.BACKUP; } + + public String getRelPath() { + Path basePath = storage.base().asPath(); + Path storagePath = storage.asPath(); + + return basePath.relativize(storagePath) + .toString(); + } + + public String getTimestampFull() { + return storage.createDateTime().format(DateTimeFormatter.ISO_DATE_TIME); + } + + public String getTimestamp() { + var ctime = storage.createDateTime(); + if (ctime.isAfter(LocalDate.now().atStartOfDay())) { + return storage.createDateTime().format(DateTimeFormatter.ISO_TIME); + } + else { + return storage.createDateTime().format(DateTimeFormatter.ISO_DATE); + } + + } } diff --git a/code/services-core/control-service/src/main/resources/templates/control/partials/storage-table.hdb b/code/services-core/control-service/src/main/resources/templates/control/partials/storage-table.hdb index d46aafa8..0d2b7304 100644 --- a/code/services-core/control-service/src/main/resources/templates/control/partials/storage-table.hdb +++ b/code/services-core/control-service/src/main/resources/templates/control/partials/storage-table.hdb @@ -1,22 +1,22 @@ - +
{{#each storage}} - - - + + + {{#each storage}} @@ -24,8 +24,11 @@ Info - - + + + + + {{/each}} {{/each}} diff --git a/code/services-core/index-service/src/test/java/nu/marginalia/index/svc/IndexQueryServiceIntegrationTestModule.java b/code/services-core/index-service/src/test/java/nu/marginalia/index/svc/IndexQueryServiceIntegrationTestModule.java index 8dabef87..23b63c50 100644 --- a/code/services-core/index-service/src/test/java/nu/marginalia/index/svc/IndexQueryServiceIntegrationTestModule.java +++ b/code/services-core/index-service/src/test/java/nu/marginalia/index/svc/IndexQueryServiceIntegrationTestModule.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.sql.SQLException; +import java.time.LocalDateTime; import java.util.Random; import java.util.UUID; @@ -52,9 +53,9 @@ public class IndexQueryServiceIntegrationTestModule extends AbstractModule { try { var fileStorageServiceMock = Mockito.mock(FileStorageService.class); - when(fileStorageServiceMock.getStorageByType(FileStorageType.SEARCH_SETS)).thenReturn(new FileStorage(null, null, null, fastDir.toString(), null)); - when(fileStorageServiceMock.getStorageByType(FileStorageType.INDEX_LIVE)).thenReturn(new FileStorage(null, null, null, fastDir.toString(), null)); - when(fileStorageServiceMock.getStorageByType(FileStorageType.INDEX_STAGING)).thenReturn(new FileStorage(null, null, null, slowDir.toString(), null)); + when(fileStorageServiceMock.getStorageByType(FileStorageType.SEARCH_SETS)).thenReturn(new FileStorage(null, null, null, LocalDateTime.now(), fastDir.toString(), null)); + when(fileStorageServiceMock.getStorageByType(FileStorageType.INDEX_LIVE)).thenReturn(new FileStorage(null, null, null, LocalDateTime.now(), fastDir.toString(), null)); + when(fileStorageServiceMock.getStorageByType(FileStorageType.INDEX_STAGING)).thenReturn(new FileStorage(null, null, null, LocalDateTime.now(), slowDir.toString(), null)); bind(FileStorageService.class).toInstance(fileStorageServiceMock);
Type Name PathPermit Temp
{{base.type}} {{base.name}} {{base.path}}{{base.permitTemp}}
Type PathDescription
CreatedDescription
{{storage.type}}{{storage.path}}{{storage.description}}{{relPath}}
{{timestamp}}{{storage.description}}