feat(quick-upload): generate better title from structured filename
Some checks failed
CI / Unit & Component Tests (push) Has been cancelled
CI / Backend Unit Tests (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
CI / Unit & Component Tests (pull_request) Successful in 2m16s
CI / Backend Unit Tests (pull_request) Successful in 2m8s
CI / E2E Tests (pull_request) Failing after 26m22s
Some checks failed
CI / Unit & Component Tests (push) Has been cancelled
CI / Backend Unit Tests (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
CI / Unit & Component Tests (pull_request) Successful in 2m16s
CI / Backend Unit Tests (pull_request) Successful in 2m8s
CI / E2E Tests (pull_request) Failing after 26m22s
titleFromFilename() mirrors the same four patterns as the frontend parseFilename() utility. Dropzone uploads to Mueller_Hans_19650312.pdf now land with title "Hans Mueller (12.03.1965)" instead of the raw stripped filename. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -65,7 +65,7 @@ public class DocumentService {
|
||||
// New uploads from the drop zone always start as incomplete
|
||||
document = Document.builder()
|
||||
.originalFilename(originalFilename)
|
||||
.title(stripExtension(originalFilename))
|
||||
.title(titleFromFilename(originalFilename))
|
||||
.status(DocumentStatus.UPLOADED)
|
||||
.metadataComplete(false)
|
||||
.build();
|
||||
@@ -356,6 +356,57 @@ public class DocumentService {
|
||||
return dot > 0 ? filename.substring(0, dot) : filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Derives a human-readable title from a structured filename.
|
||||
* Supports patterns (full match only):
|
||||
* YYYY-MM-DD_Lastname_Firstname.ext
|
||||
* YYYYMMDD_Lastname_Firstname.ext
|
||||
* Lastname_Firstname_YYYY-MM-DD.ext
|
||||
* Lastname_Firstname_YYYYMMDD.ext
|
||||
* Falls back to stripExtension for unrecognised names.
|
||||
*/
|
||||
private static final java.util.regex.Pattern FN_DATE_ISO_NAME =
|
||||
java.util.regex.Pattern.compile("^(\\d{4}-\\d{2}-\\d{2})_(\\p{L}+)_(\\p{L}+)\\.[^.]+$");
|
||||
private static final java.util.regex.Pattern FN_DATE_COMPACT_NAME =
|
||||
java.util.regex.Pattern.compile("^(\\d{8})_(\\p{L}+)_(\\p{L}+)\\.[^.]+$");
|
||||
private static final java.util.regex.Pattern FN_NAME_DATE_ISO =
|
||||
java.util.regex.Pattern.compile("^(\\p{L}+)_(\\p{L}+)_(\\d{4}-\\d{2}-\\d{2})\\.[^.]+$");
|
||||
private static final java.util.regex.Pattern FN_NAME_DATE_COMPACT =
|
||||
java.util.regex.Pattern.compile("^(\\p{L}+)_(\\p{L}+)_(\\d{8})\\.[^.]+$");
|
||||
|
||||
static String titleFromFilename(String filename) {
|
||||
if (filename == null) return null;
|
||||
java.util.regex.Matcher m;
|
||||
String dateIso, lastName, firstName;
|
||||
|
||||
if ((m = FN_DATE_ISO_NAME.matcher(filename)).matches()) {
|
||||
dateIso = m.group(1);
|
||||
lastName = m.group(2);
|
||||
firstName = m.group(3);
|
||||
} else if ((m = FN_DATE_COMPACT_NAME.matcher(filename)).matches()) {
|
||||
String compact = m.group(1);
|
||||
dateIso = compact.substring(0, 4) + "-" + compact.substring(4, 6) + "-" + compact.substring(6, 8);
|
||||
lastName = m.group(2);
|
||||
firstName = m.group(3);
|
||||
} else if ((m = FN_NAME_DATE_ISO.matcher(filename)).matches()) {
|
||||
lastName = m.group(1);
|
||||
firstName = m.group(2);
|
||||
dateIso = m.group(3);
|
||||
} else if ((m = FN_NAME_DATE_COMPACT.matcher(filename)).matches()) {
|
||||
lastName = m.group(1);
|
||||
firstName = m.group(2);
|
||||
String compact = m.group(3);
|
||||
dateIso = compact.substring(0, 4) + "-" + compact.substring(4, 6) + "-" + compact.substring(6, 8);
|
||||
} else {
|
||||
return stripExtension(filename);
|
||||
}
|
||||
|
||||
// Format date as DD.MM.YYYY for the title
|
||||
LocalDate date = LocalDate.parse(dateIso);
|
||||
String dateDisplay = String.format("%02d.%02d.%d", date.getDayOfMonth(), date.getMonthValue(), date.getYear());
|
||||
return firstName + " " + lastName + " (" + dateDisplay + ")";
|
||||
}
|
||||
|
||||
private static String sha256Hex(byte[] bytes) {
|
||||
try {
|
||||
MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
||||
|
||||
@@ -518,4 +518,40 @@ class DocumentServiceTest {
|
||||
|
||||
assertThat(count).isEqualTo(2);
|
||||
}
|
||||
|
||||
// ─── titleFromFilename ────────────────────────────────────────────────────
|
||||
|
||||
@Test
|
||||
void titleFromFilename_dateIso_name() {
|
||||
assertThat(DocumentService.titleFromFilename("1965-03-12_Mueller_Hans.pdf"))
|
||||
.isEqualTo("Hans Mueller (12.03.1965)");
|
||||
}
|
||||
|
||||
@Test
|
||||
void titleFromFilename_dateCompact_name() {
|
||||
assertThat(DocumentService.titleFromFilename("19650312_Mueller_Hans.pdf"))
|
||||
.isEqualTo("Hans Mueller (12.03.1965)");
|
||||
}
|
||||
|
||||
@Test
|
||||
void titleFromFilename_name_dateIso() {
|
||||
assertThat(DocumentService.titleFromFilename("Mueller_Hans_1965-03-12.pdf"))
|
||||
.isEqualTo("Hans Mueller (12.03.1965)");
|
||||
}
|
||||
|
||||
@Test
|
||||
void titleFromFilename_name_dateCompact() {
|
||||
assertThat(DocumentService.titleFromFilename("Mueller_Hans_19650312.pdf"))
|
||||
.isEqualTo("Hans Mueller (12.03.1965)");
|
||||
}
|
||||
|
||||
@Test
|
||||
void titleFromFilename_fallsBackToStripExtension() {
|
||||
assertThat(DocumentService.titleFromFilename("scan_001.pdf")).isEqualTo("scan_001");
|
||||
}
|
||||
|
||||
@Test
|
||||
void titleFromFilename_null_returnsNull() {
|
||||
assertThat(DocumentService.titleFromFilename(null)).isNull();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user