Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mr DLib Label, Error Handling, Display Confirmations #4596

Merged
merged 17 commits into from
Jul 11, 2019
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `#
- For automatically created groups, added ability to filter groups by entry type. [#4539](https://github.com/JabRef/jabref/issues/4539)
- We added the ability to add field names from the Preferences Dialog [#4546](https://github.com/JabRef/jabref/issues/4546)
- We added the ability change the column widths directly in the main table. [#4546](https://github.com/JabRef/jabref/issues/4546)
- We added description of how recommendations where chosen and better error handling to Related Articles tab
- We added the ability to execute default action in dialog by using with <kbd>Ctrl</kbd> + <kbd>Enter</kbd> combination [#4496](https://github.com/JabRef/jabref/issues/4496)
- We grouped and reordered the Main Menu (File, Edit, Library, Quality, Tools, and View tabs & icons). [#4666](https://github.com/JabRef/jabref/issues/4666) [#4667](https://github.com/JabRef/jabref/issues/4667) [#4668](https://github.com/JabRef/jabref/issues/4668) [#4669](https://github.com/JabRef/jabref/issues/4669) [#4670](https://github.com/JabRef/jabref/issues/4670) [#4671](https://github.com/JabRef/jabref/issues/4671) [#4672](https://github.com/JabRef/jabref/issues/4672) [#4673](https://github.com/JabRef/jabref/issues/4673)
- We added additional modifiers (capitalize, titlecase and sentencecase) to the Bibtex key generator. [#1506](https://github.com/JabRef/jabref/issues/1506)
Expand Down
15 changes: 14 additions & 1 deletion src/main/java/org/jabref/gui/entryeditor/EntryEditor.css
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,23 @@
-fx-padding: 20 20 20 20;
}

.recommendation-heading {
-fx-font-size: 14pt;
-fx-font-weight: bold;
}

.recommendation-description {
-fx-font-style: italic;
}

.recommendation-item {
-fx-padding: 0 0 0 20;
}

#bibtexSourceCodeArea .search {
-fx-fill: red;
}

.bibtexSourceCodeArea .text {
-fx-fill: -fx-text-background-color;
}
}
2 changes: 1 addition & 1 deletion src/main/java/org/jabref/gui/entryeditor/EntryEditor.java
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ private List<EntryEditorTab> createTabs() {
// Special tabs
tabs.add(new MathSciNetTab());
tabs.add(new FileAnnotationTab(panel.getAnnotationCache()));
tabs.add(new RelatedArticlesTab(preferences, dialogService));
tabs.add(new RelatedArticlesTab(this, preferences, dialogService));

// Source tab
sourceTab = new SourceTab(databaseContext, undoManager, preferences.getLatexFieldFormatterPreferences(), preferences.getImportFormatPreferences(), fileMonitor, dialogService, stateManager);
Expand Down
46 changes: 42 additions & 4 deletions src/main/java/org/jabref/gui/entryeditor/RelatedArticlesTab.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,13 @@ public class RelatedArticlesTab extends EntryEditorTab {

private static final Logger LOGGER = LoggerFactory.getLogger(RelatedArticlesTab.class);
private final EntryEditorPreferences preferences;
private final EntryEditor entryEditor;
private final DialogService dialogService;

public RelatedArticlesTab(EntryEditorPreferences preferences, DialogService dialogService) {
public RelatedArticlesTab(EntryEditor entryEditor, EntryEditorPreferences preferences, DialogService dialogService) {
setText(Localization.lang("Related articles"));
setTooltip(new Tooltip(Localization.lang("Related articles")));
this.entryEditor = entryEditor;
this.preferences = preferences;
this.dialogService = dialogService;
}
Expand All @@ -63,7 +65,12 @@ private StackPane getRelatedArticlesPane(BibEntry entry) {
.onRunning(() -> progress.setVisible(true))
.onSuccess(relatedArticles -> {
progress.setVisible(false);
root.getChildren().add(getRelatedArticleInfo(relatedArticles));
root.getChildren().add(getRelatedArticleInfo(relatedArticles, fetcher));
})
.onFailure(exception -> {
LOGGER.error("Error while fetching from Mr. DLib", exception);
progress.setVisible(false);
root.getChildren().add(getErrorInfo());
})
.executeWith(Globals.TASK_EXECUTOR);

Expand All @@ -77,13 +84,25 @@ private StackPane getRelatedArticlesPane(BibEntry entry) {
* @param list List of BibEntries of related articles
* @return VBox of related article descriptions to be displayed in the Related Articles tab
*/
private VBox getRelatedArticleInfo(List<BibEntry> list) {
private ScrollPane getRelatedArticleInfo(List<BibEntry> list, MrDLibFetcher fetcher) {
ScrollPane scrollPane = new ScrollPane();

VBox vBox = new VBox();
vBox.setSpacing(20.0);

String heading = fetcher.getHeading();
Text headingText = new Text(heading);
headingText.getStyleClass().add("recommendation-heading");
String description = fetcher.getDescription();
Text descriptionText = new Text(description);
descriptionText.getStyleClass().add("recommendation-description");
vBox.getChildren().add(headingText);
vBox.getChildren().add(descriptionText);

for (BibEntry entry : list) {
HBox hBox = new HBox();
hBox.setSpacing(5.0);
hBox.getStyleClass().add("recommendation-item");

String title = entry.getTitle().orElse("");
String journal = entry.getField(FieldName.JOURNAL).orElse("");
Expand All @@ -109,7 +128,26 @@ private VBox getRelatedArticleInfo(List<BibEntry> list) {
hBox.getChildren().addAll(titleLink, journalText, authorsText, yearText);
vBox.getChildren().add(hBox);
}
return vBox;
scrollPane.setContent(vBox);
return scrollPane;
}

/**
* Gets a ScrollPane to display error info when recommendations fail.
* @return ScrollPane to display in place of recommendations
*/
private ScrollPane getErrorInfo() {
ScrollPane scrollPane = new ScrollPane();

VBox vBox = new VBox();
vBox.setSpacing(20.0);

Text descriptionText = new Text(Localization.lang("No recommendations received from Mr. DLib for this entry."));
descriptionText.getStyleClass().add("recommendation-description");
vBox.getChildren().add(descriptionText);
scrollPane.setContent(vBox);

return scrollPane;
}

/**
Expand Down
49 changes: 40 additions & 9 deletions src/main/java/org/jabref/logic/importer/fetcher/MrDLibFetcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.jabref.logic.importer.FetcherException;
import org.jabref.logic.importer.ParserResult;
import org.jabref.logic.importer.fileformat.MrDLibImporter;
import org.jabref.logic.l10n.Localization;
import org.jabref.logic.net.URLDownload;
import org.jabref.logic.util.Version;
import org.jabref.model.database.BibDatabase;
Expand All @@ -30,8 +31,13 @@ public class MrDLibFetcher implements EntryBasedFetcher {
private static final Logger LOGGER = LoggerFactory.getLogger(MrDLibFetcher.class);
private static final String NAME = "MDL_FETCHER";
private static final String MDL_JABREF_PARTNER_ID = "1";
private static final String MDL_URL = "api.mr-dlib.org";
private static final String DEFAULT_MRDLIB_ERROR_MESSAGE = Localization.lang("Error while fetching recommendations from Mr.DLib.");
private final String LANGUAGE;
private final Version VERSION;
private String heading;
private String description;
private String recommendationSetId;


public MrDLibFetcher(String language, Version version) {
Expand All @@ -54,13 +60,13 @@ public List<BibEntry> performSearch(BibEntry entry) throws FetcherException {
try {
if (importer.isRecognizedFormat(response)) {
parserResult = importer.importDatabase(response);
heading = importer.getRecommendationsHeading();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As said earlier, I'm not a big fan that the description and header of the tab is set dynamically based on the response. But if you really think this adds a real value to the user experience than it would be fine with me. @JabRef/developers what do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We think it's beneficial to users to see how their recommendations were generated. We're open to suggestion on this from the JabRef devs.

description = importer.getRecommendationsDescription();
recommendationSetId = importer.getRecommendationSetId();
} else {
// For displaying An ErrorMessage
String error = importer.getResponseErrorMessage(response);
BibEntry errorBibEntry = new BibEntry();
errorBibEntry.setField("html_representation", error);
description = DEFAULT_MRDLIB_ERROR_MESSAGE;
BibDatabase errorBibDataBase = new BibDatabase();
errorBibDataBase.insertEntry(errorBibEntry);
parserResult = new ParserResult(errorBibDataBase);
}
} catch (IOException e) {
Expand All @@ -74,6 +80,35 @@ public List<BibEntry> performSearch(BibEntry entry) throws FetcherException {
}
}

public String getHeading() {
return heading;
}

public String getDescription() {
return description;
}

public void confirmRecommendations(String status) {
conorfos marked this conversation as resolved.
Show resolved Hide resolved
try {
URIBuilder builder = new URIBuilder();
builder.setScheme("http");
builder.setHost(MDL_URL);
builder.setPath("/v2/recommendations/" + recommendationSetId + "/status/" + status);
try {
URI uri = builder.build();
URLDownload urlDownload = new URLDownload(uri.toString());
URLDownload.bypassSSLVerification();
urlDownload.asString();
}
catch (URISyntaxException se) {
LOGGER.error("Problem connecting to Mr. DLib", se);
}

} catch (IOException e) {
LOGGER.error("Problem connecting to Mr. DLib", e);
}
}

/**
* Contact the server with the title of the selected item
*
Expand Down Expand Up @@ -106,7 +141,7 @@ private String constructQuery(String queryWithTitle) {
queryWithTitle = queryWithTitle.replaceAll("/", " ");
URIBuilder builder = new URIBuilder();
builder.setScheme("http");
builder.setHost(getMdlUrl());
builder.setHost(MDL_URL);
builder.setPath("/v2/documents/" + queryWithTitle + "/related_documents");
builder.addParameter("partner_id", MDL_JABREF_PARTNER_ID);
builder.addParameter("app_id", "jabref_desktop");
Expand All @@ -132,8 +167,4 @@ private String constructQuery(String queryWithTitle) {
}
return "";
}

private String getMdlUrl() {
return VERSION.isDevelopmentVersion() ? "api-dev.darwingoliath.com" : "api.mr-dlib.org";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,11 @@

import org.jabref.logic.importer.Importer;
import org.jabref.logic.importer.ParserResult;
import org.jabref.logic.l10n.Localization;
import org.jabref.logic.util.StandardFileType;
import org.jabref.model.database.BibDatabase;
import org.jabref.model.entry.BibEntry;
import org.jabref.model.entry.FieldName;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
Expand All @@ -29,9 +27,11 @@
*/
public class MrDLibImporter extends Importer {

private static final String DEFAULT_MRDLIB_ERROR_MESSAGE = Localization.lang("Error while fetching from Mr.DLib.");
private static final Logger LOGGER = LoggerFactory.getLogger(MrDLibImporter.class);
public ParserResult parserResult;
private String recommendationsHeading;
private String recommendationsDescription;
private String recommendationSetId;

@SuppressWarnings("unused")
@Override
Expand Down Expand Up @@ -111,12 +111,13 @@ private void parse(BufferedReader input) throws IOException {
// The Bibdatabase that gets returned in the ParserResult.
BibDatabase bibDatabase = new BibDatabase();
// The document to parse
String recommendations = convertToString(input);
String recommendationSet = convertToString(input);
JSONObject recommendationSetJson = new JSONObject(recommendationSet);
// The sorted BibEntries gets stored here later
List<RankedBibEntry> rankedBibEntries = new ArrayList<>();

// Get recommendations from response and populate bib entries
JSONObject recommendationsJson = new JSONObject(recommendations).getJSONObject("recommendations");
JSONObject recommendationsJson = recommendationSetJson.getJSONObject("recommendations");
Iterator<String> keys = recommendationsJson.keys();
while (keys.hasNext()) {
String key = keys.next();
Expand All @@ -133,6 +134,11 @@ private void parse(BufferedReader input) throws IOException {
bibDatabase.insertEntry(bibentry);
}
parserResult = new ParserResult(bibDatabase);

JSONObject label = recommendationSetJson.getJSONObject("label");
recommendationsHeading = label.getString("label-text");
recommendationsDescription = label.getString("label-description");
recommendationSetId = recommendationSetJson.getBigInteger("recommendation_set_id").toString();
}

/**
Expand All @@ -144,7 +150,7 @@ private RankedBibEntry populateBibEntry(JSONObject recommendation) {
BibEntry current = new BibEntry();

// parse each of the relevant fields into variables
String authors = isRecommendationFieldPresent(recommendation, "authors") ? getAuthorsString(recommendation) : "";
String authors = isRecommendationFieldPresent(recommendation, "authors") ? recommendation.getString("authors") : "";
String title = isRecommendationFieldPresent(recommendation, "title") ? recommendation.getString("title") : "";
String year = isRecommendationFieldPresent(recommendation, "published_year") ? Integer.toString(recommendation.getInt("published_year")) : "";
String journal = isRecommendationFieldPresent(recommendation, "published_in") ? recommendation.getString("published_in") : "";
Expand All @@ -165,43 +171,20 @@ private Boolean isRecommendationFieldPresent(JSONObject recommendation, String f
return recommendation.has(field) && !recommendation.isNull(field);
}

/**
* Creates an authors string from a JSON recommendation
* @param recommendation JSON Object recommendation from Mr. DLib
* @return A string of all authors, separated by commas and finished with a full stop.
*/
private String getAuthorsString(JSONObject recommendation) {
String authorsString = "";
JSONArray array = recommendation.getJSONArray("authors");
for (int i = 0; i < array.length(); ++i) {
authorsString += array.getString(i) + "; ";
}
int stringLength = authorsString.length();
if (stringLength > 2) {
authorsString = authorsString.substring(0, stringLength - 2) + ".";
}
return authorsString;
}

public ParserResult getParserResult() {
return parserResult;
}

/**
* Gets the error message to be returned if there has been an error in returning recommendations.
* Returns default error message if there is no message from Mr. DLib.
* @param response The response from the MDL server as a string.
* @return String error message to be shown to the user.
*/
public String getResponseErrorMessage(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
if (!jsonObject.has("message")) {
return jsonObject.getString("message");
}
} catch (JSONException ex) {
return DEFAULT_MRDLIB_ERROR_MESSAGE;
}
return DEFAULT_MRDLIB_ERROR_MESSAGE;
public String getRecommendationsHeading() {
return recommendationsHeading;
}

public String getRecommendationsDescription() {
return recommendationsDescription;
}

public String getRecommendationSetId() {
return recommendationSetId;
}

}
6 changes: 4 additions & 2 deletions src/main/resources/l10n/JabRef_en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -334,8 +334,6 @@ Error\ occurred\ when\ parsing\ entry=Error occurred when parsing entry

Error\ opening\ file=Error opening file

Error\ while\ fetching\ from\ Mr.DLib.=Error while fetching from Mr.DLib.

Error\ while\ writing=Error while writing

'%0'\ exists.\ Overwrite\ file?='%0' exists. Overwrite file?
Expand Down Expand Up @@ -570,6 +568,10 @@ Move\ up=Move up

Moved\ group\ "%0".=Moved group "%0".

No\ recommendations\ received\ from\ Mr.\ DLib\ for\ this\ entry.=No recommendations received from Mr. DLib for this entry.

Error\ while\ fetching\ recommendations\ from\ Mr.DLib.=Error while fetching recommendations from Mr.DLib.

Name=Name
Name\ formatter=Name formatter

Expand Down
Loading