Skip to content

Commit

Permalink
Fix for issue 6877: Allow users to customize the API Key (#7720)
Browse files Browse the repository at this point in the history
Co-authored-by: Carl Christian Snethlage <[email protected]>
  • Loading branch information
ruanych and calixtus authored Apr 25, 2022
1 parent 6e441ee commit 6dfc2e0
Show file tree
Hide file tree
Showing 40 changed files with 729 additions and 149 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Note that this project **does not** adhere to [Semantic Versioning](http://semve

### Added

- We enabled the user to customize the API Key for some fetchers. [#6877](https://github.com/JabRef/jabref/issues/6877)
- We added an extra option when right-clicking an entry in the Entry List to copy either the DOI or the DOI url.
- We added a fetcher for [Directory of Open Access Books (DOAB)](https://doabooks.org/) [8576](https://github.com/JabRef/jabref/issues/8576)
- We added an extra option to ask the user whether they want to open to reveal the folder holding the saved file with the file selected. [#8195](https://github.com/JabRef/jabref/issues/8195)
Expand Down
24 changes: 19 additions & 5 deletions src/main/java/org/jabref/cli/ArgumentProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,8 @@ private static Optional<ParserResult> importFile(Path file, String importFormat)
// * means "guess the format":
System.out.println(Localization.lang("Importing in unknown format") + ": " + file);

ImportFormatReader.UnknownFormatImport importResult = Globals.IMPORT_FORMAT_READER.importUnknownFormat(file, new DummyFileUpdateMonitor());
ImportFormatReader.UnknownFormatImport importResult =
Globals.IMPORT_FORMAT_READER.importUnknownFormat(file, new DummyFileUpdateMonitor());

System.out.println(Localization.lang("Format used") + ": " + importResult.format);
return Optional.of(importResult.parserResult);
Expand Down Expand Up @@ -526,7 +527,11 @@ private void saveDatabase(BibDatabase newBase, String subName) {
SavePreferences savePreferences = preferencesService.getSavePreferences();
AtomicFileWriter fileWriter = new AtomicFileWriter(Path.of(subName), StandardCharsets.UTF_8);
BibWriter bibWriter = new BibWriter(fileWriter, OS.NEWLINE);
BibDatabaseWriter databaseWriter = new BibtexDatabaseWriter(bibWriter, generalPreferences, savePreferences, Globals.entryTypesManager);
BibDatabaseWriter databaseWriter = new BibtexDatabaseWriter(
bibWriter,
generalPreferences,
savePreferences,
Globals.entryTypesManager);
databaseWriter.saveDatabase(new BibDatabaseContext(newBase));

// Show just a warning message if encoding did not work for all characters:
Expand Down Expand Up @@ -586,13 +591,20 @@ private void importPreferences() {
preferencesService.importPreferences(Path.of(cli.getPreferencesImport()));
Globals.entryTypesManager.addCustomOrModifiedTypes(preferencesService.getBibEntryTypes(BibDatabaseMode.BIBTEX),
preferencesService.getBibEntryTypes(BibDatabaseMode.BIBLATEX));
List<TemplateExporter> customExporters = preferencesService.getCustomExportFormats(Globals.journalAbbreviationRepository);
List<TemplateExporter> customExporters =
preferencesService.getCustomExportFormats(Globals.journalAbbreviationRepository);
LayoutFormatterPreferences layoutPreferences =
preferencesService.getLayoutFormatterPreferences(Globals.journalAbbreviationRepository);
SavePreferences savePreferences = preferencesService.getSavePreferencesForExport();
XmpPreferences xmpPreferences = preferencesService.getXmpPreferences();
BibDatabaseMode bibDatabaseMode = preferencesService.getGeneralPreferences().getDefaultBibDatabaseMode();
Globals.exportFactory = ExporterFactory.create(customExporters, layoutPreferences, savePreferences, xmpPreferences, bibDatabaseMode, Globals.entryTypesManager);
Globals.exportFactory = ExporterFactory.create(
customExporters,
layoutPreferences,
savePreferences,
xmpPreferences,
bibDatabaseMode,
Globals.entryTypesManager);
} catch (JabRefException ex) {
LOGGER.error("Cannot import preferences", ex);
}
Expand Down Expand Up @@ -666,7 +678,9 @@ private Optional<ParserResult> fetch(String fetchCommand) {
String engine = split[0];
String query = split[1];

Set<SearchBasedFetcher> fetchers = WebFetchers.getSearchBasedFetchers(preferencesService.getImportFormatPreferences());
Set<SearchBasedFetcher> fetchers = WebFetchers.getSearchBasedFetchers(
preferencesService.getImportFormatPreferences(),
preferencesService.getImporterPreferences());
Optional<SearchBasedFetcher> selectedFetcher = fetchers.stream()
.filter(fetcher -> fetcher.getName().equalsIgnoreCase(engine))
.findFirst();
Expand Down
25 changes: 21 additions & 4 deletions src/main/java/org/jabref/gui/EntryTypeViewModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,14 @@ public EntryTypeViewModel(PreferencesService preferences,
this.preferencesService = preferences;
this.dialogService = dialogService;
this.stateManager = stateManager;
fetchers.addAll(WebFetchers.getIdBasedFetchers(preferences.getImportFormatPreferences()));
fetchers.addAll(WebFetchers.getIdBasedFetchers(
preferences.getImportFormatPreferences(),
preferences.getImporterPreferences()));
selectedItemProperty.setValue(getLastSelectedFetcher());
idFieldValidator = new FunctionBasedValidator<>(idText, StringUtil::isNotBlank, ValidationMessage.error(Localization.lang("Required field \"%0\" is empty.", Localization.lang("ID"))));
idFieldValidator = new FunctionBasedValidator<>(
idText,
StringUtil::isNotBlank,
ValidationMessage.error(Localization.lang("Required field \"%0\" is empty.", Localization.lang("ID"))));
}

public BooleanProperty searchSuccesfulProperty() {
Expand Down Expand Up @@ -152,7 +157,14 @@ public void runFetcherWorker() {
if (result.isPresent()) {
final BibEntry entry = result.get();

ImportHandler handler = new ImportHandler(libraryTab.getBibDatabaseContext(), ExternalFileTypes.getInstance(), preferencesService, Globals.getFileUpdateMonitor(), libraryTab.getUndoManager(), stateManager, dialogService);
ImportHandler handler = new ImportHandler(
libraryTab.getBibDatabaseContext(),
ExternalFileTypes.getInstance(),
preferencesService,
Globals.getFileUpdateMonitor(),
libraryTab.getUndoManager(),
stateManager,
dialogService);
handler.importEntryWithDuplicateCheck(libraryTab.getBibDatabaseContext(), entry);

searchSuccesfulProperty.set(true);
Expand All @@ -170,7 +182,12 @@ public void runFetcherWorker() {
Localization.lang("Add entry manually"),
Localization.lang("Return to dialog"));
if (addEntryFlag) {
new NewEntryAction(libraryTab.frame(), StandardEntryType.Article, dialogService, preferencesService, stateManager).execute();
new NewEntryAction(
libraryTab.frame(),
StandardEntryType.Article,
dialogService,
preferencesService,
stateManager).execute();
searchSuccesfulProperty.set(true);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,9 @@ protected Map<BibEntry, Optional<URL>> call() {
Map<BibEntry, Optional<URL>> downloads = new ConcurrentHashMap<>();
int count = 0;
for (BibEntry entry : entries) {
FulltextFetchers fetchers = new FulltextFetchers(preferences.getImportFormatPreferences());
FulltextFetchers fetchers = new FulltextFetchers(
preferences.getImportFormatPreferences(),
preferences.getImporterPreferences());
downloads.put(entry, fetchers.findFullTextPDF(entry));
updateProgress(++count, entries.size());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,9 @@ private List<LinkedFileViewModel> findAssociatedNotLinkedFiles(BibEntry entry) {
}

public void fetchFulltext() {
FulltextFetchers fetcher = new FulltextFetchers(preferences.getImportFormatPreferences());
FulltextFetchers fetcher = new FulltextFetchers(
preferences.getImportFormatPreferences(),
preferences.getImporterPreferences());
BackgroundTask
.wrap(() -> fetcher.findFullTextPDF(entry))
.onRunning(() -> fulltextLookupInProgress.setValue(true))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ public WebSearchPaneViewModel(PreferencesService preferencesService, DialogServi
this.dialogService = dialogService;
this.stateManager = stateManager;

SortedSet<SearchBasedFetcher> allFetchers = WebFetchers.getSearchBasedFetchers(preferencesService.getImportFormatPreferences());
SortedSet<SearchBasedFetcher> allFetchers = WebFetchers.getSearchBasedFetchers(
preferencesService.getImportFormatPreferences(),
preferencesService.getImporterPreferences());
fetchers.setAll(allFetchers);

// Choose last-selected fetcher as default
Expand Down Expand Up @@ -128,7 +130,8 @@ public void search() {
}

SearchBasedFetcher activeFetcher = getSelectedFetcher();
Globals.getTelemetryClient().ifPresent(client -> client.trackEvent("search", Map.of("fetcher", activeFetcher.getName()), Map.of()));
Globals.getTelemetryClient().ifPresent(client ->
client.trackEvent("search", Map.of("fetcher", activeFetcher.getName()), Map.of()));

BackgroundTask<ParserResult> task;
task = BackgroundTask.wrap(() -> new ParserResult(activeFetcher.performSearch(query)))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<?import org.jabref.gui.commonfxcontrols.SaveOrderConfigPanel?>

<fx:root spacing="10.0" type="VBox"
xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml"
fx:controller="org.jabref.gui.preferences.importexport.ImportExportTab">
Expand All @@ -30,4 +32,16 @@
<Label text="%Grobid URL" />
<TextField fx:id="grobidURL" HBox.hgrow="ALWAYS"/>
</HBox>

<Label styleClass="sectionHeader" text="%Custom API key"/>
<HBox alignment="CENTER_LEFT" spacing="10.0">
<ComboBox fx:id="apiKeySelector" prefWidth="200.0" GridPane.columnIndex="1"/>
<TextField fx:id="customApiKey" HBox.hgrow="ALWAYS"/>
<CheckBox fx:id="useCustomApiKey" text="%Custom">
</CheckBox>
</HBox>
<HBox alignment="CENTER_LEFT" >
<Button fx:id="testCustomApiKey" text="%Check connection" onAction="#checkCustomApiKey"
prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="6"/>
</HBox>
</fx:root>
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package org.jabref.gui.preferences.importexport;

import javafx.beans.InvalidationListener;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TextField;

import org.jabref.gui.commonfxcontrols.SaveOrderConfigPanel;
import org.jabref.gui.preferences.AbstractPreferenceTabView;
import org.jabref.gui.preferences.PreferencesTab;
import org.jabref.gui.util.ViewModelListCellFactory;
import org.jabref.logic.l10n.Localization;
import org.jabref.logic.preferences.FetcherApiKey;

import com.airhacks.afterburner.views.ViewLoader;

Expand All @@ -19,6 +24,11 @@ public class ImportExportTab extends AbstractPreferenceTabView<ImportExportTabVi

@FXML private SaveOrderConfigPanel exportOrderPanel;

@FXML private ComboBox<FetcherApiKey> apiKeySelector;
@FXML private TextField customApiKey;
@FXML private CheckBox useCustomApiKey;
@FXML private Button testCustomApiKey;

@FXML private CheckBox grobidEnabled;
@FXML private TextField grobidURL;

Expand All @@ -34,7 +44,7 @@ public String getTabName() {
}

public void initialize() {
this.viewModel = new ImportExportTabViewModel(preferencesService, preferencesService.getDOIPreferences());
this.viewModel = new ImportExportTabViewModel(preferencesService, preferencesService.getDOIPreferences(), dialogService);

useCustomDOI.selectedProperty().bindBidirectional(viewModel.useCustomDOIProperty());
useCustomDOIName.textProperty().bindBidirectional(viewModel.useCustomDOINameProperty());
Expand All @@ -52,5 +62,40 @@ public void initialize() {
grobidEnabled.selectedProperty().bindBidirectional(viewModel.grobidEnabledProperty());
grobidURL.textProperty().bindBidirectional(viewModel.grobidURLProperty());
grobidURL.disableProperty().bind(grobidEnabled.selectedProperty().not());

new ViewModelListCellFactory<FetcherApiKey>()
.withText(FetcherApiKey::getName)
.install(apiKeySelector);
apiKeySelector.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
if (oldValue != null) {
updateFetcherApiKey(oldValue);
}
if (newValue != null) {
useCustomApiKey.setSelected(newValue.shouldUse());
customApiKey.setText(newValue.getKey());
}
});
customApiKey.textProperty().addListener(listener -> updateFetcherApiKey(apiKeySelector.valueProperty().get()));

customApiKey.disableProperty().bind(useCustomApiKey.selectedProperty().not());
testCustomApiKey.disableProperty().bind(useCustomApiKey.selectedProperty().not());

apiKeySelector.setItems(viewModel.fetcherApiKeys());
viewModel.selectedApiKeyProperty().bind(apiKeySelector.valueProperty());

// Content is set later
viewModel.fetcherApiKeys().addListener((InvalidationListener) change -> apiKeySelector.getSelectionModel().selectFirst());
}

private void updateFetcherApiKey(FetcherApiKey apiKey) {
if (apiKey != null) {
apiKey.setUse(useCustomApiKey.isSelected());
apiKey.setKey(customApiKey.getText().trim());
}
}

@FXML
void checkCustomApiKey() {
viewModel.checkCustomApiKey();
}
}
Loading

0 comments on commit 6dfc2e0

Please sign in to comment.