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
|
// New uploads from the drop zone always start as incomplete
|
||||||
document = Document.builder()
|
document = Document.builder()
|
||||||
.originalFilename(originalFilename)
|
.originalFilename(originalFilename)
|
||||||
.title(stripExtension(originalFilename))
|
.title(titleFromFilename(originalFilename))
|
||||||
.status(DocumentStatus.UPLOADED)
|
.status(DocumentStatus.UPLOADED)
|
||||||
.metadataComplete(false)
|
.metadataComplete(false)
|
||||||
.build();
|
.build();
|
||||||
@@ -356,6 +356,57 @@ public class DocumentService {
|
|||||||
return dot > 0 ? filename.substring(0, dot) : filename;
|
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) {
|
private static String sha256Hex(byte[] bytes) {
|
||||||
try {
|
try {
|
||||||
MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
||||||
|
|||||||
@@ -518,4 +518,40 @@ class DocumentServiceTest {
|
|||||||
|
|
||||||
assertThat(count).isEqualTo(2);
|
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