Skip to content

Commit

Permalink
Merge branch 'fixArxivHtmlImport' of github.com:JabRef/jabref into fi…
Browse files Browse the repository at this point in the history
…xArxivHtmlImport

* 'fixArxivHtmlImport' of github.com:JabRef/jabref:
  Fix focus for keywords and crossref fields (#11792)
  Fix ai chat not on fx thread (#11796)
  [AI] Add more uses statements (#11788)
  Update djl api dependency (#11787)
  Improve pdf content parser for DOIs (#11782)
  minor refactor to JabRefDialogService (#11767)
  Add more OS-dependent context to panel freeze dev documentation. (#11781)
  • Loading branch information
Siedlerchr committed Sep 20, 2024
2 parents e427409 + 541e611 commit 058b376
Show file tree
Hide file tree
Showing 12 changed files with 213 additions and 155 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv
- The browse button for a Custom exporter now opens in the directory of the current used exporter file. [#11717](https://github.com/JabRef/jabref/pull/11717)
- We improved the display of long messages in the integrity check dialog. [#11619](https://github.com/JabRef/jabref/pull/11619)
- We improved the undo/redo buttons in the main toolbar and main menu to be disabled when there is nothing to undo/redo. [#8807](https://github.com/JabRef/jabref/issues/8807)
- We improved the DOI detection in PDF imports. [#11782](https://github.com/JabRef/jabref/pull/11782)

### Fixed

Expand All @@ -73,6 +74,7 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv
- We fixed an issue where two contradicting notifications were shown when cutting an entry in the main table. [#11724](https://github.com/JabRef/jabref/pull/11724)
- We fixed an issue where unescaped braces in the arXiv fetcher were not treated. [#11704](https://github.com/JabRef/jabref/issues/11704)
- We fixed an issue where HTML instead of the fulltext pdf was downloaded when importing arXiv entries. [#4913](https://github.com/JabRef/jabref/issues/4913)
- We fixed an issue where the keywords and crossref fields were not properly focused. [#11177](https://github.com/JabRef/jabref/issues/11177)

### Removed

Expand Down
70 changes: 41 additions & 29 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ dependencies {
// YAML formatting
implementation 'org.yaml:snakeyaml:2.3'

// AI
// region AI
implementation 'dev.langchain4j:langchain4j:0.34.0'
// Even though we use jvm-openai for LLM connection, we still need this package for tokenization.
implementation('dev.langchain4j:langchain4j-open-ai:0.34.0') {
Expand All @@ -336,16 +336,19 @@ dependencies {
implementation('dev.langchain4j:langchain4j-mistral-ai:0.34.0')
implementation('dev.langchain4j:langchain4j-google-ai-gemini:0.34.0')
implementation('dev.langchain4j:langchain4j-hugging-face:0.34.0')
implementation 'ai.djl:api:0.29.0'
implementation 'ai.djl.pytorch:pytorch-model-zoo:0.30.0'
implementation 'ai.djl.huggingface:tokenizers:0.29.0'

implementation platform('ai.djl:bom:0.30.0')
implementation 'ai.djl:api'
implementation 'ai.djl.huggingface:tokenizers'
implementation 'ai.djl.pytorch:pytorch-model-zoo'
implementation 'io.github.stefanbratanov:jvm-openai:0.11.0'
// openai depends on okhttp, which needs kotlin - see https://github.com/square/okhttp/issues/5299 for details
implementation ('com.squareup.okhttp3:okhttp:4.12.0') {
exclude group: 'org.jetbrains.kotlin', module: 'kotlin-stdlib-jdk8'
}
// GemxFX also (transitively) depends on kotlin
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:2.0.20'
// endregion

implementation 'commons-io:commons-io:2.16.1'

Expand Down Expand Up @@ -738,51 +741,58 @@ jlink {

// TODO: Remove the following correction to the merged module
// The module descriptor automatically generated by the plugin for the merged module contained some invalid entries.
// This is based on ./gradlew suggestMergedModuleInfo, sort, strip ";"", comment non-used modules, and include the suggested directives here.
// However, we need to fine-tune this manually (non-alphabetic order)
// This is based on ./gradlew suggestMergedModuleInfo, sort, strip ";"", remove non-used modules, and include the suggested directives here.
mergedModule {
requires 'javafx.base'
requires 'javafx.controls'
requires 'javafx.fxml'
requires 'javafx.graphics'
requires 'javafx.media'
requires 'javafx.swing'

requires 'com.google.gson'
requires 'com.fasterxml.jackson.annotation'
requires 'com.fasterxml.jackson.databind'
requires 'com.fasterxml.jackson.core'
requires 'com.fasterxml.jackson.datatype.jdk8'
requires 'jakarta.xml.bind'
requires 'java.compiler'
requires 'java.datatransfer'
requires 'java.desktop'
requires 'java.logging'
requires 'java.management'
requires 'java.naming'
requires 'java.net.http'
requires 'java.rmi'
requires 'java.scripting'
requires 'java.security.jgss'
requires 'java.security.sasl'
requires 'java.sql'
requires 'java.sql.rowset'
requires 'java.transaction.xa'
requires 'java.rmi'
requires 'java.xml'
requires 'javafx.base'
requires 'javafx.controls'
requires 'javafx.fxml'
requires 'javafx.graphics'
requires 'javafx.media'
requires 'javafx.swing'
requires 'jdk.jsobject'
requires 'jdk.security.jgss'
requires 'jdk.unsupported'
requires 'jdk.unsupported.desktop'
requires 'jdk.security.jgss'
requires 'jdk.xml.dom'
requires 'com.google.gson'
requires 'org.jsoup'
requires 'org.slf4j'
requires 'jakarta.xml.bind'
requires 'org.apache.commons.lang3'
requires 'org.apache.commons.logging'
requires 'org.apache.commons.text'
requires 'org.apache.commons.logging';
uses 'org.mariadb.jdbc.credential.CredentialPlugin'
requires 'org.freedesktop.dbus'
requires 'org.jsoup'
requires 'org.slf4j'
uses 'ai.djl.engine.EngineProvider'
uses 'ai.djl.repository.RepositoryFactory'
uses 'ai.djl.repository.zoo.ZooProvider'
uses 'dev.langchain4j.spi.prompt.PromptTemplateFactory'
uses 'kong.unirest.core.json.JsonEngine'
uses 'org.eclipse.jgit.lib.GpgSigner'
uses 'org.eclipse.jgit.transport.SshSessionFactory'
uses 'org.mariadb.jdbc.LocalInfileInterceptor'
uses 'org.mariadb.jdbc.authentication.AuthenticationPlugin'
uses 'org.mariadb.jdbc.credential.CredentialPlugin'
uses 'org.mariadb.jdbc.tls.TlsSocketPlugin'
uses 'org.mariadb.jdbc.LocalInfileInterceptor'
uses 'org.eclipse.jgit.transport.SshSessionFactory'
uses 'org.eclipse.jgit.lib.GpgSigner'
uses 'kong.unirest.core.json.JsonEngine';
uses 'ai.djl.repository.zoo.ZooProvider';

provides 'org.mariadb.jdbc.tls.TlsSocketPlugin' with 'org.mariadb.jdbc.internal.protocol.tls.DefaultTlsSocketPlugin'
provides 'java.sql.Driver' with 'org.postgresql.Driver'
provides 'org.mariadb.jdbc.authentication.AuthenticationPlugin' with 'org.mariadb.jdbc.internal.com.send.authentication.CachingSha2PasswordPlugin',
Expand All @@ -800,9 +810,11 @@ jlink {
'org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider'
provides 'kong.unirest.core.json.JsonEngine' with 'kong.unirest.modules.gson.GsonEngine';
provides 'ai.djl.repository.zoo.ZooProvider' with 'ai.djl.engine.rust.zoo.RsZooProvider',
'ai.djl.huggingface.zoo.HfZooProvider',
'ai.djl.pytorch.zoo.PtZooProvider',
'ai.djl.repository.zoo.DefaultZooProvider';
'ai.djl.huggingface.zoo.HfZooProvider',
'ai.djl.pytorch.zoo.PtZooProvider',
'ai.djl.repository.zoo.DefaultZooProvider';
provides 'ai.djl.engine.EngineProvider' with 'ai.djl.engine.rust.RsEngineProvider',
'ai.djl.pytorch.engine.PtEngineProvider';
}

jpackage {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,10 @@ java.lang.UnsupportedClassVersionError: org/javamodularity/moduleplugin/ModuleSy

This is likely caused by improper integration of your OS or Desktop Environment with your password prompting program or password manager. Ensure that these are working properly, then restart your machine and attempt to run the program.

For reference, see issue [#11766](https://github.com/JabRef/jabref/issues/11766).
In an ideal scenario, a password prompt should appear when the program starts, provided the keyring your OS uses has not already been unlocked. However, the implementation details vary depending on the operating system, which makes troubleshooting more complex.

For Windows and macOS users, specific configurations may differ based on the password management tools and settings used, so ensure your OS's password management system is properly set up and functioning.

For Linux users, ensure that your [xdg-desktop-portal](https://wiki.archlinux.org/title/XDG_Desktop_Portal) settings refer to active and valid portal implementations installed on your system. However, there might be other factors involved, so additional research or guidance specific to your distribution may be necessary.

For reference, see the discussion at issue [#11766](https://github.com/JabRef/jabref/issues/11766).
6 changes: 5 additions & 1 deletion src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -144,14 +144,18 @@

// region AI
requires ai.djl.api;
uses ai.djl.repository.zoo.ZooProvider;
requires ai.djl.pytorch_model_zoo;
requires ai.djl.tokenizers;
requires jvm.openai;
requires langchain4j;
requires langchain4j.core;
requires langchain4j.hugging.face;
requires langchain4j.mistral.ai;
requires langchain4j.open.ai;
uses ai.djl.engine.EngineProvider;
uses ai.djl.repository.RepositoryFactory;
uses ai.djl.repository.zoo.ZooProvider;
uses dev.langchain4j.spi.prompt.PromptTemplateFactory;
// endregion

// region: Lucene
Expand Down
13 changes: 7 additions & 6 deletions src/main/java/org/jabref/gui/Base.css
Original file line number Diff line number Diff line change
Expand Up @@ -1427,17 +1427,15 @@ We want to have a look that matches our icons in the tool-bar */
-fx-label-padding: 5 0 10 10;
}

.chips-pane > .editor {
.tags-field {
-fx-pref-height: 30px;
-fx-padding: 0px 0px 0px -8px;
-fx-margin: 0em;
-fx-border-style: none;
-fx-background-color: -fx-outer-border, -fx-control-inner-background;
}

.tags-field {
-fx-pref-height: 30px;
-fx-margin: 0em;
-fx-border-style: none;
.tags-field:focused {
-fx-border-color: -jr-accent;
}

.tags-field > .flow-pane > .tag-view {
Expand All @@ -1452,6 +1450,9 @@ We want to have a look that matches our icons in the tool-bar */

.tags-field-editor {
-fx-border-width: 0;
-fx-text-fill: -fx-focused-text-base-color;
-fx-highlight-text-fill: -fx-text-inner-color;
-fx-highlight-fill: derive(-jr-accent, 20%);
}

.searchBar:invalid {
Expand Down
63 changes: 32 additions & 31 deletions src/main/java/org/jabref/gui/JabRefDialogService.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.stream.Collectors;

import javafx.concurrent.Task;
import javafx.geometry.Pos;
Expand Down Expand Up @@ -99,9 +97,9 @@ private FXDialog createDialog(AlertType type, String title, String content) {
return alert;
}

private FXDialog createDialogWithOptOut(AlertType type, String title, String content,
private FXDialog createDialogWithOptOut(String title, String content,
String optOutMessage, Consumer<Boolean> optOutAction) {
FXDialog alert = new FXDialog(type, title, true);
FXDialog alert = new FXDialog(AlertType.CONFIRMATION, title, true);
// Need to force the alert to layout in order to grab the graphic as we are replacing the dialog pane with a custom pane
alert.getDialogPane().applyCss();
Node graphic = alert.getDialogPane().getGraphic();
Expand Down Expand Up @@ -135,7 +133,7 @@ public static String shortenDialogMessage(String dialogMessage) {
if (dialogMessage.length() < JabRefDialogService.DIALOG_SIZE_LIMIT) {
return dialogMessage.trim();
}
return (dialogMessage.substring(0, Math.min(dialogMessage.length(), JabRefDialogService.DIALOG_SIZE_LIMIT)) + "...").trim();
return (dialogMessage.substring(0, JabRefDialogService.DIALOG_SIZE_LIMIT) + "...").trim();
}

private <T> ChoiceDialog<T> createChoiceDialog(String title, String content, String okButtonLabel, T defaultChoice, Collection<T> choices) {
Expand Down Expand Up @@ -226,16 +224,7 @@ public void showErrorDialogAndWait(FetcherException fetcherException) {
String localizedMessage = fetcherException.getLocalizedMessage();
Optional<SimpleHttpResponse> httpResponse = fetcherException.getHttpResponse();
if (httpResponse.isPresent()) {
int statusCode = httpResponse.get().statusCode();
if (statusCode == 401) {
this.showInformationDialogAndWait(failedTitle, Localization.lang("Access denied. You are not authorized to access this resource. Please check your credentials and try again. If you believe you should have access, please contact the administrator for assistance.") + "\n\n" + localizedMessage);
} else if (statusCode == 403) {
this.showInformationDialogAndWait(failedTitle, Localization.lang("Access denied. You do not have permission to access this resource. Please contact the administrator for assistance or try a different action.") + "\n\n" + localizedMessage);
} else if (statusCode == 404) {
this.showInformationDialogAndWait(failedTitle, Localization.lang("The requested resource could not be found. It seems that the file you are trying to download is not available or has been moved. Please verify the URL and try again. If you believe this is an error, please contact the administrator for further assistance.") + "\n\n" + localizedMessage);
} else {
this.showErrorDialogAndWait(failedTitle, Localization.lang("Something is wrong on JabRef side. Please check the URL and try again.") + "\n\n" + localizedMessage);
}
this.showInformationDialogAndWait(failedTitle, getContentByCode(httpResponse.get().statusCode()) + "\n\n" + localizedMessage);
} else if (fetcherException instanceof FetcherClientException) {
this.showErrorDialogAndWait(failedTitle, Localization.lang("Something is wrong on JabRef side. Please check the URL and try again.") + "\n\n" + localizedMessage);
} else if (fetcherException instanceof FetcherServerException) {
Expand Down Expand Up @@ -288,7 +277,7 @@ public boolean showConfirmationDialogAndWait(String title, String content,
@Override
public boolean showConfirmationDialogWithOptOutAndWait(String title, String content,
String optOutMessage, Consumer<Boolean> optOutAction) {
FXDialog alert = createDialogWithOptOut(AlertType.CONFIRMATION, title, content, optOutMessage, optOutAction);
FXDialog alert = createDialogWithOptOut(title, content, optOutMessage, optOutAction);
alert.getButtonTypes().setAll(ButtonType.YES, ButtonType.NO);
return alert.showAndWait().filter(buttonType -> buttonType == ButtonType.YES).isPresent();
}
Expand All @@ -297,7 +286,7 @@ public boolean showConfirmationDialogWithOptOutAndWait(String title, String cont
public boolean showConfirmationDialogWithOptOutAndWait(String title, String content,
String okButtonLabel, String cancelButtonLabel,
String optOutMessage, Consumer<Boolean> optOutAction) {
FXDialog alert = createDialogWithOptOut(AlertType.CONFIRMATION, title, content, optOutMessage, optOutAction);
FXDialog alert = createDialogWithOptOut(title, content, optOutMessage, optOutAction);
ButtonType okButtonType = new ButtonType(okButtonLabel, ButtonBar.ButtonData.YES);
ButtonType cancelButtonType = new ButtonType(cancelButtonLabel, ButtonBar.ButtonData.NO);
alert.getButtonTypes().setAll(okButtonType, cancelButtonType);
Expand Down Expand Up @@ -388,7 +377,7 @@ public <V> void showProgressDialogAndWait(String title, String content, Task<V>
}

@Override
public <V> Optional<ButtonType> showBackgroundProgressDialogAndWait(String title, String content, StateManager stateManager) {
public Optional<ButtonType> showBackgroundProgressDialogAndWait(String title, String content, StateManager stateManager) {
TaskProgressView<Task<?>> taskProgressView = new TaskProgressView<>();
EasyBind.bindContent(taskProgressView.getTasks(), stateManager.getRunningBackgroundTasks());
taskProgressView.setRetainTasks(false);
Expand Down Expand Up @@ -424,25 +413,24 @@ public void notify(String message) {
// The event log is not that user friendly (different purpose).
LOGGER.info(message);

UiTaskExecutor.runInJavaFXThread(() -> {
UiTaskExecutor.runInJavaFXThread(() ->
Notifications.create()
.text(message)
.position(Pos.BOTTOM_CENTER)
.hideAfter(TOAST_MESSAGE_DISPLAY_TIME)
.owner(mainWindow)
.threshold(5,
Notifications.create()
.title(Localization.lang("Last notification"))
.text(
"(" + Localization.lang("Check the event log to see all notifications") + ")"
+ "\n\n" + message)
.onAction(e -> {
ErrorConsoleAction ec = new ErrorConsoleAction();
ec.execute();
}))
Notifications.create()
.title(Localization.lang("Last notification"))
.text(
"(" + Localization.lang("Check the event log to see all notifications") + ")"
+ "\n\n" + message)
.onAction(e -> {
ErrorConsoleAction ec = new ErrorConsoleAction();
ec.execute();
}))
.hideCloseButton()
.show();
});
.show());
}

@Override
Expand Down Expand Up @@ -472,7 +460,7 @@ public Optional<Path> showDirectorySelectionDialog(DirectoryDialogConfiguration
public List<Path> showFileOpenDialogAndGetMultipleFiles(FileDialogConfiguration fileDialogConfiguration) {
FileChooser chooser = getConfiguredFileChooser(fileDialogConfiguration);
List<File> files = chooser.showOpenMultipleDialog(mainWindow);
return files != null ? files.stream().map(File::toPath).collect(Collectors.toList()) : Collections.emptyList();
return files != null ? files.stream().map(File::toPath).toList() : List.of();
}

private DirectoryChooser getConfiguredDirectoryChooser(DirectoryDialogConfiguration directoryDialogConfiguration) {
Expand Down Expand Up @@ -520,4 +508,17 @@ public void showCustomWindow(BaseWindow window) {
window.applyStylesheets(mainWindow.getScene().getStylesheets());
window.show();
}

private String getContentByCode(int statusCode) {
return switch (statusCode) {
case 401 ->
Localization.lang("Access denied. You are not authorized to access this resource. Please check your credentials and try again. If you believe you should have access, please contact the administrator for assistance.");
case 403 ->
Localization.lang("Access denied. You do not have permission to access this resource. Please contact the administrator for assistance or try a different action.");
case 404 ->
Localization.lang("The requested resource could not be found. It seems that the file you are trying to download is not available or has been moved. Please verify the URL and try again. If you believe this is an error, please contact the administrator for further assistance.");
default ->
Localization.lang("Something is wrong on JabRef side. Please check the URL and try again.");
};
}
}
Loading

0 comments on commit 058b376

Please sign in to comment.