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

Externalize strings, update junit dependency #12

Merged
merged 2 commits into from
Nov 30, 2023
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: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ dependencies {
implementation "ai.djl:api:$djlVersion"

testImplementation libs.junit
testRuntimeOnly libs.junit.engine
testRuntimeOnly libs.junit.platform

}

Expand Down
17 changes: 2 additions & 15 deletions src/main/java/qupath/ext/djl/DjlTools.java
Original file line number Diff line number Diff line change
Expand Up @@ -252,32 +252,19 @@ public static Engine getEngine(String name, boolean downloadIfNeeded) throws Ill
else
System.setProperty("offline", "true");

// If trying to instantiate a TensorFlow engine for the first time,
// we need to reset the javacpp platform properties for the preload
// path to be correctly identified
if (ENGINE_TENSORFLOW.equalsIgnoreCase(name) && !loadedEngines.contains(name)) {
try {
var f = Loader.class.getDeclaredField("platformProperties");
f.setAccessible(true);
f.set(null, null);
} catch (Exception e) {
logger.error("Unable to reset JavaCPP platform properties: " + e.getLocalizedMessage(), e);
}
}

var engine = Engine.getEngine(name);
if (engine != null)
loadedEngines.add(name);
return engine;
} catch (Exception e) {
if (downloadIfNeeded)
logger.error("Unable to get engine " + name + ": " + e.getLocalizedMessage(), e);
logger.error("Unable to get engine " + name + ": " + e.getMessage(), e);
else {
var msg = e.getLocalizedMessage();
if (msg == null)
logger.warn("Unable to get engine {}", name);
else
logger.warn("Unable to get engine {} ({})", name, e.getLocalizedMessage());
logger.warn("Unable to get engine {} ({})", name, e.getMessage());
}
return null;
} finally {
Expand Down
47 changes: 24 additions & 23 deletions src/main/java/qupath/ext/djl/ui/DjlEngineCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import javafx.geometry.Pos;
import javafx.scene.Cursor;
import javafx.scene.Node;
import javafx.scene.layout.StackPane;
import javafx.scene.text.TextAlignment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -54,7 +55,6 @@
import javafx.scene.control.Tooltip;
import javafx.scene.layout.GridPane;
import javafx.scene.shape.Circle;
import javafx.stage.Modality;
import javafx.stage.Stage;
import qupath.ext.djl.DjlTools;
import qupath.fx.dialogs.Dialogs;
Expand Down Expand Up @@ -144,7 +144,9 @@ private void init() {

var status = available.computeIfAbsent(name, n -> new SimpleObjectProperty<>(EngineStatus.UNKNOWN));

var path = Utils.getEngineCacheDir(name);
// Names seem to be lower case in practice
// This matters on Linux, since otherwise the directory can't be found/opened
var path = Utils.getEngineCacheDir(name.toLowerCase());

String tooltip = String.format(bundle.getString("tooltip.engine"), name);
String labelNameText = name;
Expand Down Expand Up @@ -183,17 +185,17 @@ private void init() {
var tooltipDownload = new Tooltip();
tooltipDownload.textProperty().bind(Bindings.createStringBinding(() -> {
switch (status.get()) {
case AVAILABLE:
return name + " is available";
case UNAVAILABLE:
return name + " is not available - click to download it";
case FAILED:
return name + " download & initialization failed - you can try again, but it may not be supported on this platform";
case PENDING:
return name + " download pending";
case UNKNOWN:
default:
return name + " download status is unknown";
case AVAILABLE:
return String.format(bundle.getString("tooltip.download.available"), name);
case FAILED:
return String.format(bundle.getString("tooltip.download.failed"), name);
case PENDING:
return String.format(bundle.getString("tooltip.download.pending"), name);
case UNAVAILABLE:
return String.format(bundle.getString("tooltip.download.unavailable"), name);
case UNKNOWN:
default:
return String.format(bundle.getString("tooltip.download.unknown"), name);
}
}, status));
btnDownload.setTooltip(tooltipDownload);
Expand All @@ -216,7 +218,7 @@ private void init() {
logger.debug("Cannot open {} - directory does not exist", path);
});

var labelVersion = new Label("");
var labelVersion = new Label(bundle.getString("label.version.unknown"));
labelVersion.setMaxWidth(Double.MAX_VALUE);

var labelVersionLabel = createLabelForKey("label.version");
Expand All @@ -234,7 +236,9 @@ private void init() {
updateVersionFromStatus(n, name, labelVersion);
});

pane.add(circle, 0, row, 1, 2);
var circlePane = new StackPane(circle);
circlePane.setPadding(new Insets(5));
pane.add(circlePane, 0, row, 1, 2);

GridPaneUtils.addGridRow(pane, row++, 1, null, labelPathLabel, labelPath);
GridPaneUtils.addGridRow(pane, row++, 1, null, labelVersionLabel, labelVersion);
Expand All @@ -243,13 +247,13 @@ private void init() {
GridPaneUtils.setToExpandGridPaneWidth(labelName, labelPath, btnDownload);

// Update the engine status quietly
checkEngineStatus(name, status, -1, true);
// checkEngineStatus(name, status, -1, true);
}

stage = new Stage();
stage.setTitle(TITLE);
stage.initOwner(QuPathGUI.getInstance().getStage());
stage.initModality(Modality.APPLICATION_MODAL);
// stage.initModality(Modality.WINDOW_MODAL);
stage.setScene(new Scene(pane));
}

Expand All @@ -270,7 +274,7 @@ private static void updateVersionFromStatus(EngineStatus status, String engineNa
logger.error("Error updating engine version: {}", e.getMessage(), e);
}
}
labelVersion.setText("");
labelVersion.setText(bundle.getString("label.version.unknown"));
labelVersion.setTooltip(null);
}

Expand Down Expand Up @@ -342,8 +346,7 @@ private void checkEngineStatus(String name, ObjectProperty<EngineStatus> status,
// Wait until the timeout - engine might already be available & return quickly
var result = future.get(timeoutMillis, TimeUnit.MILLISECONDS);
if (result != null && result.booleanValue()) {
Dialogs.showInfoNotification(TITLE, name + " is available!");
return;
Dialogs.showInfoNotification(TITLE, String.format(bundle.getString("notify.engine.available"), name));
} else
logger.debug("No engine available for {}", name);
} catch (InterruptedException e) {
Expand All @@ -368,7 +371,7 @@ private Boolean checkEngineAvailability(String name, ObjectProperty<EngineStatus

if (!GeneralTools.isLinux() && LINUX_ONLY.contains(name)) {
if (!doQuietly)
Dialogs.showErrorMessage(TITLE, name + " is only available on Linux, sorry");
Dialogs.showErrorMessage(TITLE, String.format(bundle.getString("notify.engine.linuxOnly"), name));
updateStatus(status, EngineStatus.UNAVAILABLE);
return Boolean.FALSE;
}
Expand Down Expand Up @@ -400,8 +403,6 @@ private Boolean checkEngineAvailability(String name, ObjectProperty<EngineStatus
isAvailable = DjlTools.getEngine(name, true) != null;
if (isAvailable) {
updateStatus(status, EngineStatus.AVAILABLE);
if (!doQuietly)
Dialogs.showInfoNotification(TITLE, name + " is now available!");
} else {
updateStatus(status, EngineStatus.UNAVAILABLE);
if (!doQuietly) {
Expand Down
10 changes: 9 additions & 1 deletion src/main/resources/qupath/ext/djl/ui/strings.properties
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,26 @@ cuda.appleSilicon = CUDA is not supported on Apple Silicon.\n\
label.defaultName = %s (default)
label.path = Path:
label.version = Version:
label.version.unknown = ?
label.cudaVersion = CUDA version:
label.computeCapability = Compute capability:

tooltip.engine = Engine: %s
tooltip.openPath = Double-click to open engine path
tooltip.pathMissing = Engine path does not exist

notify.engine.available = %s is available!
notify.engine.linuxOnly = %s is only available on Linux, sorry

button.download = Download
button.download.available = Available
button.download.failed = Try again
button.download.pending = Pending (please wait)
button.download.unknown = Check / Download
button.download.unavailable = Download

engines.title = Engines
tooltip.download.available = %s is available
tooltip.download.failed = %s download & initialization failed - you can try again, but it may not be supported on this platform
tooltip.download.pending = %s download pending
tooltip.download.unknown = %s download status is unknown
tooltip.download.unavailable = %s is not available - click to download it