Skip to content

Commit

Permalink
Use local and downloaded dirs, check zip content, less eager downloading
Browse files Browse the repository at this point in the history
  • Loading branch information
alanocallaghan committed Dec 6, 2024
1 parent 8d0b418 commit 19e870b
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 25 deletions.
30 changes: 15 additions & 15 deletions src/main/java/qupath/ext/instanseg/core/InstanSegModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,22 +79,13 @@ public static InstanSegModel fromURL(String name, String version, URL browserDow
* Check if the model has been downloaded already.
* @return True if the model has a known path that exists and is valid, or if a suitable directory can be found in the localModelPath
*/
public boolean isDownloaded(Path localModelPath) {
public boolean isValid() {
// Check path first - *sometimes* the model might be downloaded, but have a name
// that doesn't match with the filename (although we'd prefer this didn't happen...)
if (path != null && model != null && isValidModel(path))
return true;
if (!Files.exists(localModelPath.resolve(getFolderName(name, version)))) {
// The model may have been deleted or renamed - we won't be able to load it
return false;
}

try {
download(localModelPath);
} catch (IOException e) {
logger.error("Model directory exists but is not valid", e);
}
return path != null && model != null;
// The model may have been deleted or renamed - we won't be able to load it
return false;
}

/**
Expand Down Expand Up @@ -276,7 +267,8 @@ private Optional<BioimageIoSpec.BioimageIoModel> getModel() {
}

private static Path downloadZipIfNeeded(URL url, Path localDirectory, String filename) throws IOException {
var zipFile = localDirectory.resolve(Path.of(filename + ".zip"));
Files.createDirectories(localDirectory); // just in case...
var zipFile = localDirectory.resolve(filename + ".zip");
if (!isDownloadedAlready(zipFile)) {
try (InputStream stream = url.openStream()) {
try (ReadableByteChannel readableByteChannel = Channels.newChannel(stream)) {
Expand All @@ -290,8 +282,16 @@ private static Path downloadZipIfNeeded(URL url, Path localDirectory, String fil
}

private static boolean isDownloadedAlready(Path zipFile) {
// todo: validate contents somehow
return Files.exists(zipFile);
if (!Files.exists(zipFile)) {
return false;
}
try {
BioimageIoSpec.parseModel(zipFile.toFile());
} catch (IOException e) {
logger.warn("Invalid zip file", e);
return false;
}
return true;
}

private Path unzipIfNeeded(Path zipFile) throws IOException {
Expand Down
12 changes: 6 additions & 6 deletions src/main/java/qupath/ext/instanseg/ui/InstanSegController.java
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ private void updateInputChannels(ImageData<BufferedImage> imageData) {
comboInputChannels.getCheckModel().checkIndices(IntStream.range(0, 3).toArray());
var modelDir = InstanSegUtils.getModelDirectory().orElse(null);
// todo: not clear why this is needed. is this handling the checkcombobox weirdness on clearing checks, or?
if (model != null && modelDir != null && model.isDownloaded(modelDir)) {
if (model != null && modelDir != null && model.isValid()) {
var modelChannels = model.getNumChannels();
if (modelChannels.isPresent()) {
int nModelChannels = modelChannels.get();
Expand Down Expand Up @@ -464,7 +464,7 @@ private void configureRunning() {
return true;
}
var modelDir = InstanSegUtils.getModelDirectory().orElse(null);
if (modelDir != null && !model.isDownloaded(modelDir)) {
if (modelDir != null && !model.isValid()) {
return false; // to enable "download and run"
}
return false;
Expand All @@ -488,7 +488,7 @@ private void refreshModelChoice() {
return;

var modelDir = InstanSegUtils.getModelDirectory().orElse(null);
boolean isDownloaded = modelDir != null && model.isDownloaded(modelDir);
boolean isDownloaded = modelDir != null && model.isValid();
if (!isDownloaded || qupath.getImageData() == null) {
return;
}
Expand Down Expand Up @@ -545,7 +545,7 @@ private InstanSegModel downloadModel(InstanSegModel model, Path modelDir) {
try {
Dialogs.showInfoNotification(resources.getString("title"),
String.format(resources.getString("ui.popup.fetching"), model.getName()));
model.download(modelDir);
model.download(modelDir.resolve("downloaded"));
Dialogs.showInfoNotification(resources.getString("title"),
String.format(resources.getString("ui.popup.available"), model.getName()));
FXUtils.runOnApplicationThread(() -> {
Expand Down Expand Up @@ -767,12 +767,12 @@ private void runInstanSeg(InstanSegModel model) {
return;
}

if (!model.isDownloaded(modelPath)) {
if (!model.isValid()) {
if (!Dialogs.showYesNoDialog(resources.getString("title"), resources.getString("ui.model-popup")))
return;
downloadModelAsync(model)
.thenAccept((InstanSegModel suppliedModel) -> {
if (suppliedModel == null || !suppliedModel.isDownloaded(modelPath)) {
if (suppliedModel == null || !suppliedModel.isValid()) {
Dialogs.showErrorNotification(resources.getString("title"), String.format(resources.getString("error.localModel")));
} else {
runInstanSeg(suppliedModel);
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/qupath/ext/instanseg/ui/InstanSegUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public static BooleanBinding createModelDownloadedBinding(ObservableValue<Instan
return false;
}
var modelDir = getModelDirectory().orElse(null);
return modelDir != null && model.isDownloaded(modelDir);
return modelDir != null && model.isValid();
},
selectedModel, needsUpdating,
InstanSegPreferences.modelDirectoryProperty());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ private String getWarningText() {
if (deviceChoiceBox.getSelectionModel().isEmpty())
return resources.getString("ui.error.no-device");
var modelDir = InstanSegUtils.getModelDirectory().orElse(null);
if (modelDir != null && modelChoiceBox.getSelectionModel().getSelectedItem().isDownloaded(modelDir)) {
if (modelDir != null && modelChoiceBox.getSelectionModel().getSelectedItem().isValid()) {
// shouldn't happen if downloaded anyway!
var modelChannels = modelChoiceBox.getSelectionModel().getSelectedItem().getNumChannels();
if (modelChannels.isPresent()) {
Expand Down
3 changes: 1 addition & 2 deletions src/main/java/qupath/ext/instanseg/ui/ModelListCell.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package qupath.ext.instanseg.ui;

import javafx.scene.control.ContentDisplay;
import javafx.scene.control.ListCell;
import javafx.scene.control.Tooltip;
import org.controlsfx.glyphfont.FontAwesome;
Expand Down Expand Up @@ -32,7 +31,7 @@ public void updateItem(InstanSegModel model, boolean empty) {
} else {
setText(model.toString());
var dir = InstanSegUtils.getLocalModelDirectory().orElse(null);
if (dir != null && !model.isDownloaded(dir)) {
if (dir != null && !model.isValid()) {
setGraphic(web);
tooltip.setText(resources.getString("ui.model-not-downloaded.tooltip"));
setTooltip(tooltip);
Expand Down

0 comments on commit 19e870b

Please sign in to comment.