diff --git a/jabgui/src/main/java/org/jabref/gui/frame/MainMenu.java b/jabgui/src/main/java/org/jabref/gui/frame/MainMenu.java index 9a934f1f2e80..6d9f89de95e3 100644 --- a/jabgui/src/main/java/org/jabref/gui/frame/MainMenu.java +++ b/jabgui/src/main/java/org/jabref/gui/frame/MainMenu.java @@ -19,7 +19,6 @@ import org.jabref.gui.citationkeypattern.GenerateCitationKeyAction; import org.jabref.gui.cleanup.CleanupAction; import org.jabref.gui.clipboard.ClipBoardManager; -import org.jabref.gui.collab.MergeLibraryAction; import org.jabref.gui.consistency.ConsistencyCheckAction; import org.jabref.gui.copyfiles.CopyFilesAction; import org.jabref.gui.documentviewer.ShowDocumentViewerAction; @@ -67,7 +66,6 @@ import org.jabref.gui.preview.PreviewControls; import org.jabref.gui.pseudonymize.PseudonymizeAction; import org.jabref.gui.push.GuiPushToApplicationCommand; -import org.jabref.gui.relatedwork.RelatedWorkAction; import org.jabref.gui.search.RebuildFulltextSearchIndexAction; import org.jabref.gui.shared.ConnectToSharedDatabaseCommand; import org.jabref.gui.shared.PullChangesFromSharedAction; @@ -181,8 +179,6 @@ private void createMenu() { new SeparatorMenuItem(), - factory.createMenuItem(StandardActions.MERGE_LIBRARY, new MergeLibraryAction(dialogService, stateManager, preferences, taskExecutor, undoManager, frame)), - factory.createSubMenu(StandardActions.IMPORT, factory.createMenuItem(StandardActions.IMPORT_INTO_CURRENT_LIBRARY, new ImportCommand(frame, ImportCommand.ImportMethod.TO_EXISTING, preferences, stateManager, fileUpdateMonitor, taskExecutor, dialogService)), factory.createMenuItem(StandardActions.IMPORT_INTO_NEW_LIBRARY, new ImportCommand(frame, ImportCommand.ImportMethod.AS_NEW, preferences, stateManager, fileUpdateMonitor, taskExecutor, dialogService))), @@ -325,9 +321,8 @@ private void createMenu() { tools.getItems().addAll( factory.createMenuItem(StandardActions.PARSE_LATEX, new ParseLatexAction(stateManager)), factory.createMenuItem(StandardActions.NEW_SUB_LIBRARY_FROM_AUX, new NewSubLibraryAction(frame, stateManager, dialogService)), - factory.createMenuItem(StandardActions.NEW_LIBRARY_FROM_PDF_ONLINE, new NewLibraryFromPdfActionOnline(frame, stateManager, dialogService, preferences, taskExecutor)), - factory.createMenuItem(StandardActions.NEW_LIBRARY_FROM_PDF_OFFLINE, new NewLibraryFromPdfActionOffline(frame, stateManager, dialogService, preferences, taskExecutor)), - factory.createMenuItem(StandardActions.EXTRACT_RELATED_WORK_COMMENTS, new RelatedWorkAction(dialogService, stateManager, preferences)), + factory.createMenuItem(StandardActions.NEW_LIBRARY_FROM_PDF_ONLINE, new NewLibraryFromPdfActionOnline(frame, stateManager, dialogService, preferences, taskExecutor, aiService)), + factory.createMenuItem(StandardActions.NEW_LIBRARY_FROM_PDF_OFFLINE, new NewLibraryFromPdfActionOffline(frame, stateManager, dialogService, preferences, taskExecutor, aiService)), factory.createMenuItem(StandardActions.PSEUDONYMIZE_LIBRARY, new PseudonymizeAction(stateManager, dialogService, preferences)), new SeparatorMenuItem(), diff --git a/jabgui/src/main/java/org/jabref/gui/maintable/NewLibraryFromPdfAction.java b/jabgui/src/main/java/org/jabref/gui/maintable/NewLibraryFromPdfAction.java index c42ab7f68cec..f4daab41d1a4 100644 --- a/jabgui/src/main/java/org/jabref/gui/maintable/NewLibraryFromPdfAction.java +++ b/jabgui/src/main/java/org/jabref/gui/maintable/NewLibraryFromPdfAction.java @@ -8,6 +8,7 @@ import org.jabref.gui.StateManager; import org.jabref.gui.actions.SimpleCommand; import org.jabref.gui.util.FileDialogConfiguration; +import org.jabref.logic.ai.AiService; import org.jabref.logic.importer.ParserResult; import org.jabref.logic.l10n.Localization; import org.jabref.logic.preferences.CliPreferences; @@ -29,6 +30,7 @@ public abstract class NewLibraryFromPdfAction extends SimpleCommand { private static final Logger LOGGER = LoggerFactory.getLogger(NewLibraryFromPdfAction.class); protected final CliPreferences preferences; + protected final AiService aiService; private final LibraryTabContainer libraryTabContainer; private final StateManager stateManager; @@ -40,12 +42,14 @@ public NewLibraryFromPdfAction( StateManager stateManager, DialogService dialogService, CliPreferences preferences, - TaskExecutor taskExecutor) { + TaskExecutor taskExecutor, + AiService aiService) { this.libraryTabContainer = libraryTabContainer; this.stateManager = stateManager; this.dialogService = dialogService; this.preferences = preferences; this.taskExecutor = taskExecutor; + this.aiService = aiService; } @Override diff --git a/jabgui/src/main/java/org/jabref/gui/maintable/NewLibraryFromPdfActionOffline.java b/jabgui/src/main/java/org/jabref/gui/maintable/NewLibraryFromPdfActionOffline.java index 4c2fb12b72a7..152c25d3cba9 100644 --- a/jabgui/src/main/java/org/jabref/gui/maintable/NewLibraryFromPdfActionOffline.java +++ b/jabgui/src/main/java/org/jabref/gui/maintable/NewLibraryFromPdfActionOffline.java @@ -6,6 +6,7 @@ import org.jabref.gui.DialogService; import org.jabref.gui.LibraryTabContainer; import org.jabref.gui.StateManager; +import org.jabref.logic.ai.AiService; import org.jabref.logic.importer.ParserResult; import org.jabref.logic.importer.fileformat.pdf.RuleBasedBibliographyPdfImporter; import org.jabref.logic.preferences.CliPreferences; @@ -15,8 +16,8 @@ public class NewLibraryFromPdfActionOffline extends NewLibraryFromPdfAction { private final RuleBasedBibliographyPdfImporter ruleBasedBibliographyPdfImporter; - public NewLibraryFromPdfActionOffline(LibraryTabContainer libraryTabContainer, StateManager stateManager, DialogService dialogService, CliPreferences preferences, TaskExecutor taskExecutor) { - super(libraryTabContainer, stateManager, dialogService, preferences, taskExecutor); + public NewLibraryFromPdfActionOffline(LibraryTabContainer libraryTabContainer, StateManager stateManager, DialogService dialogService, CliPreferences preferences, TaskExecutor taskExecutor, AiService aiService) { + super(libraryTabContainer, stateManager, dialogService, preferences, taskExecutor, aiService); // Use the importer keeping the numbers (instead of generating keys; which is the other constructor) this.ruleBasedBibliographyPdfImporter = new RuleBasedBibliographyPdfImporter(); diff --git a/jabgui/src/main/java/org/jabref/gui/maintable/NewLibraryFromPdfActionOnline.java b/jabgui/src/main/java/org/jabref/gui/maintable/NewLibraryFromPdfActionOnline.java index 3b8c2fc0f5d3..49f514e3552d 100644 --- a/jabgui/src/main/java/org/jabref/gui/maintable/NewLibraryFromPdfActionOnline.java +++ b/jabgui/src/main/java/org/jabref/gui/maintable/NewLibraryFromPdfActionOnline.java @@ -1,25 +1,47 @@ -package org.jabref.gui.maintable; +package org.jabref.gui.maintable; import java.nio.file.Path; +import java.util.List; import java.util.concurrent.Callable; import org.jabref.gui.DialogService; import org.jabref.gui.LibraryTabContainer; import org.jabref.gui.StateManager; +import org.jabref.logic.ai.AiService; import org.jabref.logic.importer.ParserResult; +import org.jabref.logic.importer.fileformat.pdf.CitationsFromPdf; import org.jabref.logic.importer.util.GrobidService; import org.jabref.logic.preferences.CliPreferences; import org.jabref.logic.util.TaskExecutor; +import org.jabref.model.entry.BibEntry; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class NewLibraryFromPdfActionOnline extends NewLibraryFromPdfAction { - public NewLibraryFromPdfActionOnline(LibraryTabContainer libraryTabContainer, StateManager stateManager, DialogService dialogService, CliPreferences preferences, TaskExecutor taskExecutor) { - super(libraryTabContainer, stateManager, dialogService, preferences, taskExecutor); + private static final Logger LOGGER = LoggerFactory.getLogger(NewLibraryFromPdfActionOnline.class); + + public NewLibraryFromPdfActionOnline(LibraryTabContainer libraryTabContainer, StateManager stateManager, DialogService dialogService, CliPreferences preferences, TaskExecutor taskExecutor, AiService aiService) { + super(libraryTabContainer, stateManager, dialogService, preferences, taskExecutor, aiService); } @Override protected Callable getParserResultCallable(Path path) { - return () -> new ParserResult( - new GrobidService(this.preferences.getGrobidPreferences()).processReferences(path, preferences.getImportFormatPreferences())); + return () -> { + List entries; + try { + entries = new GrobidService(this.preferences.getGrobidPreferences()) + .processReferences(path, preferences.getImportFormatPreferences()); + } catch (Exception e) { + LOGGER.warn("Grobid failed, falling back to LLM", e); + entries = List.of(); + } + if (entries.isEmpty()) { + entries = CitationsFromPdf.extractCitationsUsingLLM( + this.aiService, this.preferences.getImportFormatPreferences(), path).getDatabase().getEntries(); + } + return new ParserResult(entries); + }; } } diff --git a/jablib/src/main/java/org/jabref/logic/importer/fileformat/pdf/CitationsFromPdf.java b/jablib/src/main/java/org/jabref/logic/importer/fileformat/pdf/CitationsFromPdf.java index f7f8bdd56aca..58295850c0bf 100644 --- a/jablib/src/main/java/org/jabref/logic/importer/fileformat/pdf/CitationsFromPdf.java +++ b/jablib/src/main/java/org/jabref/logic/importer/fileformat/pdf/CitationsFromPdf.java @@ -3,8 +3,10 @@ import java.nio.file.Path; import org.jabref.logic.ai.AiService; +import org.jabref.logic.importer.ImportFormatPreferences; import org.jabref.logic.importer.ParserResult; import org.jabref.logic.importer.plaincitation.LlmPlainCitationParser; +import org.jabref.logic.preferences.CliPreferences; import org.jabref.logic.preferences.JabRefCliPreferences; import org.jabref.logic.util.CurrentThreadTaskExecutor; import org.jabref.logic.util.NotificationService; @@ -26,6 +28,10 @@ public static ParserResult extractCitationsUsingGrobid(JabRefCliPreferences pref /// As [NotificationService], one can pass `LOGGER::info` public static ParserResult extractCitationsUsingLLM(JabRefCliPreferences preferences, NotificationService notificationService, Path path) { + return extractCitationsUsingLLM((CliPreferences) preferences, notificationService, path); + } + + public static ParserResult extractCitationsUsingLLM(CliPreferences preferences, NotificationService notificationService, Path path) { try (AiService aiService = new AiService( preferences.getAiPreferences(), preferences.getFilePreferences(), @@ -36,4 +42,9 @@ public static ParserResult extractCitationsUsingLLM(JabRefCliPreferences prefere return importer.importDatabase(path); } } + + public static ParserResult extractCitationsUsingLLM(AiService aiService, ImportFormatPreferences importFormatPreferences, Path path) { + LlmPlainCitationParser importer = new LlmPlainCitationParser(aiService.getTemplatesService(), importFormatPreferences, aiService.getChatLanguageModel()); + return importer.importDatabase(path); + } }