feat: Add PDF Upload endpoint to EntryResource#14963
Conversation
|
Note that your PR will not be reviewed/accepted until you have gone through the mandatory checks in the description and marked each of them them exactly in the format of |
koppor
left a comment
There was a problem hiding this comment.
Minor comments in line.
Please add entry to CHANGELOG.md
jabsrv/src/main/java/org/jabref/http/server/resources/EntryResource.java
Outdated
Show resolved
Hide resolved
| // 2. Save stream to temporary file | ||
| // We must save to a temp file first because LinkedFileHandler requires an existing Path to generate the suggested filename based on content/metadata. | ||
| // We use the target directory to ensure we are on the same file system. | ||
| java.nio.file.Path tempFile = Files.createTempFile(targetDir, "jabref-upload", ".pdf"); |
There was a problem hiding this comment.
Plesae re-add the timestamp here again - as suffix after -upload. Use ISO 8601 here - example: 20201209T160953Z . No need for time hones.
There was a problem hiding this comment.
// 3. Save stream to temporary file
String timestamp = ZonedDateTime.now(ZoneId.of("UTC")).format(DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss'Z'"));
java.nio.file.Path tempFile = Files.createTempFile(targetDir, "jabref-upload-" + timestamp + "-", ".pdf");
Files.copy(fileInputStream, tempFile, StandardCopyOption.REPLACE_EXISTING);
Should I change to this?
jabsrv/src/main/java/org/jabref/http/server/resources/EntryResource.java
Show resolved
Hide resolved
jabsrv/src/main/java/org/jabref/http/server/resources/EntryResource.java
Show resolved
Hide resolved
| @POST | ||
| @Path("files") | ||
| @Consumes("application/pdf") | ||
| public void addFile(@PathParam("id") String id, @PathParam("entryId") String entryId, InputStream fileInputStream) throws IOException { |
| Files.copy(fileInputStream, tempFile, StandardCopyOption.REPLACE_EXISTING); | ||
|
|
||
| // 3. Create LinkedFile | ||
| LinkedFile linkedFile = new LinkedFile("", tempFile, "PDF"); |
There was a problem hiding this comment.
Java offers strong typing.
Use
| LinkedFile linkedFile = new LinkedFile("", tempFile, "PDF"); | |
| LinkedFile linkedFile = new LinkedFile("", tempFile, StandardFileType.PDF); |
|
|
||
| // 3. Create LinkedFile | ||
| LinkedFile linkedFile = new LinkedFile("", tempFile, "PDF"); | ||
| LinkedFileHandler fileHandler = new LinkedFileHandler(linkedFile, entry, databaseContext, preferences.getFilePreferences()); |
There was a problem hiding this comment.
Move this after 4., because it belongs to there - and not to step 3.
There was a problem hiding this comment.
// 4. Create LinkedFile
LinkedFile linkedFile = new LinkedFile(tempFile.getFileName().toString(), tempFile, "PDF");
// 5. Rename to suggested pattern (e.g. Author - Title.pdf)
LinkedFileHandler fileHandler = new LinkedFileHandler(linkedFile, entry, databaseContext, preferences.getFilePreferences());
| // 4. Rename to suggested pattern (e.g. Author - Title.pdf) | ||
| boolean renameSuccessful = fileHandler.renameToSuggestedName(); | ||
| if (!renameSuccessful) { | ||
| throw new IOException("Failed to rename file to suggested pattern"); |
There was a problem hiding this comment.
Remember you are in a HTTP Server context -- You can create better replies here... If you use JAX-RS response (see https://github.com/JabRef/jabref/pull/14963/changes#r2753557164), you can do.
- Change return type to Response (200/204) - Use ISO 8601 timestamp for temp files - Use LinkedFileHandler.renameToSuggestedName() for logic reuse - Use StandardFileType constant - Remove fallback directory logic (fail fast)
|
I have updated the code in the new commit. Please review it again. |
|
CHANGELOG.md can be skipped this time as this is not that imporant. In furute, also add a CHANGELOG.md entry |
Review Summary by QodoAdd PDF file upload endpoint to EntryResource
WalkthroughsDescription• Implements POST endpoint for uploading PDF files to entries • Saves uploaded stream to temporary file with ISO 8601 timestamp • Renames file using LinkedFileHandler for consistent naming patterns • Links file to BibEntry and returns appropriate HTTP response Diagramflowchart LR
A["PDF Upload Request"] --> B["Validate Entry Exists"]
B --> C["Get Target Directory"]
C --> D["Save to Temp File"]
D --> E["Create LinkedFile"]
E --> F["Rename to Suggested Pattern"]
F --> G["Add to BibEntry"]
G --> H["Return Response"]
File Changes1. jabsrv/src/main/java/org/jabref/http/server/resources/EntryResource.java
|
Code Review by Qodo
1. Missing id/entryId validation
|
|
qodo feedback can be adressed as follow up |
…4902 * upstream/main: (23 commits) Some more recipes from OpenRewrite (JabRef#15030) feat: Add PDF Upload endpoint to EntryResource (JabRef#14963) Heuristics also used at batch (JabRef#15025) Fix cleanup-pr.yml New Crowdin updates (JabRef#15035) Use patched Gradle version (JabRef#15034) Add OpenAlex-based Citation Fetcher (JabRef#15023) Update null annotaitons at EntryBasedFetcher (JabRef#15024) Fix CHANGELOG.md test Use _ for unused variables (JabRef#15028) Use ubuntu-latest for checkstyle and javadoc Update Gradle Wrapper from 9.3.0-jabref-2 to 9.3.1 (JabRef#15021) Use "ubuntu-slim" for most workflows (JabRef#15019) Refine GroupsTree (JabRef#15013) New Crowdin updates (JabRef#15018) Added Clear group option (JabRef#15017) Chore(deps): Bump com.uber.nullaway:nullaway from 0.12.15 to 0.13.1 in /versions (JabRef#15006) Chore(deps): Bump tools.jackson:jackson-bom in /versions (JabRef#15007) No rush in Docker building Yaml issue workaround ...
…es/jablib/src/main/resources/csl-styles-6c79ffe * upstream/main: (68 commits) Chore(deps): Bump org.apache.httpcomponents.client5:httpclient5 (#15060) Chore(deps): Bump com.google.errorprone:error_prone_core in /versions (#15059) Chore(deps): Bump de.undercouch.download:de.undercouch.download.gradle.plugin (#15057) Chore(deps): Bump org.postgresql:postgresql in /versions (#15058) Chore(deps): Bump de.undercouch.download:de.undercouch.download.gradle.plugin (#15056) Updates on Wednesday, not on Sunday Add screenshot requirement (#15050) Switch image for javadoc Better docker layer caching during build (#15042) New Crowdin updates (#15045) Chore: reuse shared 'setup-gradle' in all places in test-code.yml (#15043) Chore: add 'testlens-app/setup-testlens' GH action (#15044) Add: HTTP Server and LSP server toggles to quick settings (#14972) Some more recipes from OpenRewrite (#15030) feat: Add PDF Upload endpoint to EntryResource (#14963) Heuristics also used at batch (#15025) Fix cleanup-pr.yml New Crowdin updates (#15035) Use patched Gradle version (#15034) Add OpenAlex-based Citation Fetcher (#15023) ...
Closes Research_Cockpit#91
Summary
This PR implements the missing
POST /libraries/{id}/entries/{entryId}/filesendpoint in the HTTP API. This allows external tools (like browser extensions) to upload and attach PDF files to existing bibliographic entries.Changes
EntryResource.java: Added theaddFilemethod to handlemultipart/form-dataor raw PDF streams.LinkedFileHandler.renameToSuggestedName()to automatically rename the file according to user preferences (e.g.,Author - Title.pdf) and handle collisions.BadRequestExceptionif not configured).BibEntry.Steps to test
Test2026).curl -v -X POST -H "Content-Type: application/pdf" --data-binary @path/to/your/test.pdf http://localhost:23119/libraries/current/entries/Test2026/filesMandatory checks
CHANGELOG.mdin a way that is understandable for the average user (if change is visible to the user)