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

Download many files in one go #1869

Merged
merged 4 commits into from
Aug 27, 2016
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `#

### Changed
- Added integrity check for fields with BibTeX keys, e.g., `crossref` and `related`, to check that the key exists
- [#1496](https://github.com/JabRef/jabref/issues/1496) Keep track of which entry a downloaded file belongs to
- Made it possible to download multiple entries in one action

### Fixed
- Fixed NullPointerException when opening search result window for an untitled database
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/net/sf/jabref/cli/ArgumentProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ private List<ParserResult> importAndOpenFiles() {
// BIB files to open. Other files, and files that could not be opened
// as bib, we try to import instead.
boolean bibExtension = aLeftOver.toLowerCase(Locale.ENGLISH).endsWith("bib");
ParserResult pr = null;
ParserResult pr = ParserResult.getNullResult();
if (bibExtension) {
pr = OpenDatabase.loadDatabaseOrAutoSave(aLeftOver, false,
Globals.prefs.getImportFormatPreferences());
Expand Down
28 changes: 15 additions & 13 deletions src/main/java/net/sf/jabref/external/DownloadExternalFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import net.sf.jabref.logic.net.URLDownload;
import net.sf.jabref.logic.util.OS;
import net.sf.jabref.logic.util.io.FileUtil;
import net.sf.jabref.model.entry.BibEntry;
import net.sf.jabref.preferences.JabRefPreferences;

import org.apache.commons.logging.Log;
Expand All @@ -43,15 +44,16 @@ public class DownloadExternalFile {

private final JabRefFrame frame;
private final BibDatabaseContext databaseContext;
private final String bibtexKey;
private final BibEntry entry;
private FileListEntryEditor editor;
private boolean downloadFinished;
private boolean dontShowDialog;

public DownloadExternalFile(JabRefFrame frame, BibDatabaseContext databaseContext, String bibtexKey) {

public DownloadExternalFile(JabRefFrame frame, BibDatabaseContext databaseContext, BibEntry entry) {
this.frame = frame;
this.databaseContext = databaseContext;
this.bibtexKey = bibtexKey;
this.entry = entry;
}

/**
Expand Down Expand Up @@ -155,8 +157,8 @@ public void download(URL url, final DownloadCallback callback) throws IOExceptio
}
final String suggestDir = directory == null ? System.getProperty("user.home") : directory;
File file = new File(new File(suggestDir), suggestedName);
FileListEntry entry = new FileListEntry("", file.getCanonicalPath(), suggestedType);
editor = new FileListEntryEditor(frame, entry, true, false, databaseContext);
FileListEntry fileListEntry = new FileListEntry("", file.getCanonicalPath(), suggestedType);
editor = new FileListEntryEditor(frame, fileListEntry, true, false, databaseContext);
editor.getProgressBar().setIndeterminate(true);
editor.setOkEnabled(false);
editor.setExternalConfirm(closeEntry -> {
Expand All @@ -181,7 +183,8 @@ public void download(URL url, final DownloadCallback callback) throws IOExceptio
}
// Editor closed. Go on:
if (editor.okPressed()) {
File toFile = directory == null ? new File(entry.link) : expandFilename(directory, entry.link);
File toFile = directory == null ? new File(fileListEntry.link) : expandFilename(directory,
fileListEntry.link);
String dirPrefix;
if (directory == null) {
dirPrefix = null;
Expand All @@ -202,12 +205,13 @@ public void download(URL url, final DownloadCallback callback) throws IOExceptio

// If the local file is in or below the main file directory, change the
// path to relative:
if ((directory != null) && entry.link.startsWith(directory) &&
(entry.link.length() > dirPrefix.length())) {
entry = new FileListEntry(entry.description, entry.link.substring(dirPrefix.length()), entry.type);
if ((dirPrefix != null) && fileListEntry.link.startsWith(directory)
&& (fileListEntry.link.length() > dirPrefix.length())) {
fileListEntry = new FileListEntry(fileListEntry.description,
fileListEntry.link.substring(dirPrefix.length()), fileListEntry.type);
}

callback.downloadComplete(entry);
callback.downloadComplete(fileListEntry);
} catch (IOException ex) {
LOGGER.warn("Problem downloading file", ex);
}
Expand Down Expand Up @@ -253,10 +257,8 @@ private void downloadFinished() {
editor.getProgressBar().setValue(editor.getProgressBar().getMaximum());
}

// FIXME: will break download if no bibtexkey is present!
private String getSuggestedFileName(String suffix) {
String plannedName = FileUtil.createFileNameFromPattern(databaseContext.getDatabase(),
frame.getCurrentBasePanel().getSelectedEntries().get(0),
String plannedName = FileUtil.createFileNameFromPattern(databaseContext.getDatabase(), entry,
Globals.prefs.get(JabRefPreferences.IMPORT_FILENAMEPATTERN),
Globals.prefs.getLayoutFormatterPreferences(Globals.journalAbbreviationLoader));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ private boolean tryXmpImport(String fileName, ExternalFileType fileType, NamedCo
panel.getBibDatabaseContext().getFileDirectory(Globals.prefs.getFileDirectoryPreferences()))
.toString();
} else {
if (renameCheckBox.isSelected()) {
if (renameCheckBox.isSelected() || (single == null)) {
destFilename = fileName;
} else {
destFilename = single.getCiteKey() + "." + fileType.getExtension();
Expand Down
106 changes: 66 additions & 40 deletions src/main/java/net/sf/jabref/external/FindFullTextAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

import javax.swing.JOptionPane;

Expand All @@ -26,9 +30,10 @@
public class FindFullTextAction extends AbstractWorker {
private static final Log LOGGER = LogFactory.getLog(FindFullTextAction.class);

private static final int warningLimit = 10; // The minimum number of selected entries to ask the user for confirmation

private final BasePanel basePanel;
private BibEntry entry;
private Optional<URL> result;
private final Map<Optional<URL>, BibEntry> downloads = new ConcurrentHashMap<>();

public FindFullTextAction(BasePanel basePanel) {
this.basePanel = basePanel;
Expand All @@ -41,52 +46,73 @@ public void init() throws Throwable {

@Override
public void run() {
if (basePanel.getSelectedEntries().size() != 1) {
basePanel.output(Localization.lang("This operation requires exactly one item to be selected."));
result = Optional.empty();
} else {
entry = basePanel.getSelectedEntries().get(0);
if (basePanel.getSelectedEntries().size() >= warningLimit) {
String[] options = new String[]{Localization.lang("Look up full text documents"), Localization.lang("Cancel")};
int answer = JOptionPane.showOptionDialog(basePanel.frame(),
Localization.lang(
"You are about to look up full text documents for %0 entries.",
String.valueOf(basePanel.getSelectedEntries().size())) + "\n"
+ Localization.lang("Do you still want to continue?"),
Localization.lang("Look up full text documents"), JOptionPane.OK_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE, null, options, options[0]);
if (answer != JOptionPane.OK_OPTION) {
basePanel.output(Localization.lang("Operation canceled."));
return;
}
}
for (BibEntry entry : basePanel.getSelectedEntries()) {
FulltextFetchers fft = new FulltextFetchers();
result = fft.findFullTextPDF(entry);
downloads.put(fft.findFullTextPDF(entry), entry);
}
}

@Override
public void update() {
if (result.isPresent()) {
List<String> dirs = basePanel.getBibDatabaseContext()
.getFileDirectory(Globals.prefs.getFileDirectoryPreferences());
if (dirs.isEmpty()) {
JOptionPane.showMessageDialog(basePanel.frame(),
Localization.lang("Main file directory not set!") + " " + Localization.lang("Preferences")
+ " -> " + Localization.lang("External programs"),
Localization.lang("Directory not found"), JOptionPane.ERROR_MESSAGE);
return;
}
String bibtexKey = entry.getCiteKey();
// TODO: this needs its own thread as it blocks the UI!
DownloadExternalFile def = new DownloadExternalFile(basePanel.frame(), basePanel.getBibDatabaseContext(), bibtexKey);
try {
def.download(result.get(), file -> {
FileListTableModel tm = new FileListTableModel();
entry.getField(FieldName.FILE).ifPresent(tm::setContent);
tm.addEntry(tm.getRowCount(), file);
String newValue = tm.getStringRepresentation();
UndoableFieldChange edit = new UndoableFieldChange(entry, FieldName.FILE,
entry.getField(FieldName.FILE).orElse(null), newValue);
entry.setField(FieldName.FILE, newValue);
basePanel.getUndoManager().addEdit(edit);
basePanel.markBaseChanged();
});
} catch (IOException e) {
LOGGER.warn("Problem downloading file", e);
List<Optional<URL>> remove = new ArrayList<>();
for (Entry<Optional<URL>, BibEntry> download : downloads.entrySet()) {
BibEntry entry = download.getValue();
Optional<URL> result = download.getKey();
if (result.isPresent()) {
List<String> dirs = basePanel.getBibDatabaseContext()
.getFileDirectory(Globals.prefs.getFileDirectoryPreferences());
if (dirs.isEmpty()) {
JOptionPane.showMessageDialog(basePanel.frame(),
Localization.lang("Main file directory not set!") + " " + Localization.lang("Preferences")
+ " -> " + Localization.lang("External programs"),
Localization.lang("Directory not found"), JOptionPane.ERROR_MESSAGE);
return;
}
DownloadExternalFile def = new DownloadExternalFile(basePanel.frame(),
basePanel.getBibDatabaseContext(), entry);
try {
def.download(result.get(), file -> {
FileListTableModel tm = new FileListTableModel();
entry.getField(FieldName.FILE).ifPresent(tm::setContent);
tm.addEntry(tm.getRowCount(), file);
String newValue = tm.getStringRepresentation();
UndoableFieldChange edit = new UndoableFieldChange(entry, FieldName.FILE,
entry.getField(FieldName.FILE).orElse(null), newValue);
entry.setField(FieldName.FILE, newValue);
basePanel.getUndoManager().addEdit(edit);
basePanel.markBaseChanged();
});
} catch (IOException e) {
LOGGER.warn("Problem downloading file", e);
}
basePanel.output(Localization.lang("Finished downloading full text document for entry %0.",
entry.getCiteKeyOptional().orElse(Localization.lang("undefined"))));
} else {
String title = Localization.lang("Full text document download failed");
String message = Localization.lang("Full text document download failed for entry %0.",
entry.getCiteKeyOptional().orElse(Localization.lang("undefined")));

basePanel.output(message);
JOptionPane.showMessageDialog(basePanel.frame(), message, title, JOptionPane.ERROR_MESSAGE);
}
basePanel.output(Localization.lang("Finished downloading full text document"));
remove.add(result);
}
else {
String message = Localization.lang("Full text document download failed");
basePanel.output(message);
JOptionPane.showMessageDialog(basePanel.frame(), message, message, JOptionPane.ERROR_MESSAGE);
for (Optional<URL> result : remove) {
downloads.remove(result);
}
}
}
2 changes: 1 addition & 1 deletion src/main/java/net/sf/jabref/external/MoveFileAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ public void actionPerformed(ActionEvent event) {

}

if (!newFile.equals(file)) {
if ((newFile != null) && !newFile.equals(file)) {
try {
boolean success = file.renameTo(newFile);
if (!success) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ private void downloadFile() {
}
}
DownloadExternalFile def = new DownloadExternalFile(frame,
frame.getCurrentBasePanel().getBibDatabaseContext(), bibtexKey.orElse(null));
frame.getCurrentBasePanel().getBibDatabaseContext(), entryEditor.getEntry());
try {
def.download(this);
} catch (IOException ex) {
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/net/sf/jabref/gui/groups/GroupsTree.java
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ public void dragOver(DropTargetDragEvent dtde) {
} else if (dtde
.isDataFlavorSupported(TransferableEntrySelection.FLAVOR_INTERNAL)) {
// check if node accepts explicit assignment
if (path == null) {
if (target == null) {
dtde.rejectDrag();
} else {
// this would be the place to check if the dragging entries
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -438,13 +438,10 @@ public void entryListComplete() {
}

/**
* Generate key for the selected entry only.
* Generate key for an entry.
*/
private void generateKeySelectedEntry() {
if (selectionModel.getSelected().size() != 1) {
return;
}
BibEntry entry = selectionModel.getSelected().get(0);
private void generateKeyForEntry(BibEntry entry) {

entries.getReadWriteLock().writeLock().lock();
try {
BibDatabase database;
Expand Down Expand Up @@ -1166,21 +1163,19 @@ public void actionPerformed(ActionEvent actionEvent) {
return;
}
entry = selectionModel.getSelected().get(0);
Optional<String> bibtexKey = entry.getCiteKeyOptional();
if (!bibtexKey.isPresent()) {
if (!entry.getCiteKeyOptional().isPresent()) {
int answer = JOptionPane.showConfirmDialog(frame,
Localization.lang("This entry has no BibTeX key. Generate key now?"),
Localization.lang("Download file"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
if (answer == JOptionPane.OK_OPTION) {
generateKeySelectedEntry();
bibtexKey = entry.getCiteKeyOptional();
generateKeyForEntry(entry);
}
}
DownloadExternalFile def = new DownloadExternalFile(frame, bibDatabaseContext, bibtexKey.get());
DownloadExternalFile def = new DownloadExternalFile(frame, bibDatabaseContext, entry);
try {
def.download(this);
} catch (IOException ex) {
LOGGER.warn("Could not downlod file", ex);
LOGGER.warn("Could not download file", ex);
}
}

Expand Down Expand Up @@ -1218,7 +1213,7 @@ public void actionPerformed(ActionEvent actionEvent) {
Localization.lang("This entry has no BibTeX key. Generate key now?"),
Localization.lang("Download file"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
if (answer == JOptionPane.OK_OPTION) {
generateKeySelectedEntry();
generateKeyForEntry(entry);
} else {
return; // Can't go on without the bibtex key.
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,14 @@ public int compare(BibEntry e1, BibEntry e2) {
}
}

if ((f1 == null) && (f2 == null)) {
return next == null ? idCompare(e1, e2) : next.compare(e1, e2);
}
if ((f1 != null) && (f2 == null)) {
return -1;
if (f2 == null) {
if (f1 == null) {
return next == null ? idCompare(e1, e2) : next.compare(e1, e2);
} else {
return -1;
}
}

if (f1 == null) { // f2 != null here automatically
return 1;
}
Expand Down
7 changes: 6 additions & 1 deletion src/main/java/net/sf/jabref/logic/util/io/FileUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,8 @@ public static List<File> getListOfLinkedFiles(List<BibEntry> bes, List<String> f
*/
public static String createFileNameFromPattern(BibDatabase database, BibEntry entry,
String fileNamePattern, LayoutFormatterPreferences prefs) {
String targetName = entry.getCiteKeyOptional().orElse("default");
String targetName = null;

StringReader sr = new StringReader(fileNamePattern);
Layout layout = null;
try {
Expand All @@ -390,6 +391,10 @@ public static String createFileNameFromPattern(BibDatabase database, BibEntry en
if (layout != null) {
targetName = layout.doLayout(entry, database);
}

if ((targetName == null) || targetName.isEmpty()) {
targetName = entry.getCiteKeyOptional().orElse("default");
}
//Removes illegal characters from filename
targetName = FileNameCleaner.cleanFileName(targetName);
return targetName;
Expand Down
7 changes: 6 additions & 1 deletion src/main/resources/l10n/JabRef_da.properties
Original file line number Diff line number Diff line change
Expand Up @@ -869,7 +869,6 @@ Sort_the_following_fields_as_numeric_fields=Sorter_følgende_felter_som_numerisk
Line_%0\:_Found_corrupted_BibTeX_key.=Linje_%0\:_Fandt_ødelagt_BibTeX-nøgle.
Line_%0\:_Found_corrupted_BibTeX_key_(contains_whitespaces).=Linje_%0\:_Fandt_ødelagt_BibTeX-nøgle_(indeholder_blanktegn).
Line_%0\:_Found_corrupted_BibTeX_key_(comma_missing).=Linje_%0\:_Fandt_ødelagt_BibTeX-nøgle_(manglende_komma).
Finished_downloading_full_text_document=Download_af_fuldtekst-dokument_afsluttet
Full_text_document_download_failed=Download_af_fuldtekst-dokument_mislykkedes
Update_to_current_column_order=Brug_nuværende_kolonnerækkefølge

Expand Down Expand Up @@ -1772,3 +1771,9 @@ Opens_JabRef's_website=
Opens_a_link_where_the_current_development_version_can_be_downloaded=
See_what_has_been_changed_in_the_JabRef_versions=
Referenced_BibTeX_key_does_not_exist=


Finished_downloading_full_text_document_for_entry_%0.=
Full_text_document_download_failed_for_entry_%0.=
Look_up_full_text_documents=
You_are_about_to_look_up_full_text_documents_for_%0_entries.=
Loading