Skip to content

Commit 92a010c

Browse files
adjust to API, check with provided http client
1 parent 3e8f57e commit 92a010c

File tree

4 files changed

+66
-25
lines changed

4 files changed

+66
-25
lines changed

pom.xml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,12 @@
3939
<project.jdk.version>25</project.jdk.version>
4040

4141
<!-- runtime dependencies -->
42-
4342
<api.version>1.8.0-SNAPSHOT</api.version>
43+
<slf4j.version>2.0.17</slf4j.version>
44+
<jackson.version>2.20.0</jackson.version>
4445
<secret-service.version>2.0.1-alpha</secret-service.version>
4546
<kdewallet.version>1.4.0</kdewallet.version>
4647
<flatpakupdateportal.version>1.1.0</flatpakupdateportal.version>
47-
<slf4j.version>2.0.17</slf4j.version>
4848
<appindicator.version>1.4.2</appindicator.version>
4949

5050
<!-- test dependencies -->
@@ -87,6 +87,12 @@
8787
<artifactId>slf4j-api</artifactId>
8888
<version>${slf4j.version}</version>
8989
</dependency>
90+
<dependency>
91+
<groupId>com.fasterxml.jackson.core</groupId>
92+
<artifactId>jackson-databind</artifactId>
93+
<version>${jackson.version}</version>
94+
</dependency>
95+
9096
<dependency>
9197
<groupId>de.swiesend</groupId>
9298
<artifactId>secret-service</artifactId>

src/main/java/module-info.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
requires org.purejava.portal;
2323
requires de.swiesend.secretservice;
2424
requires java.xml;
25+
requires java.net.http;
26+
requires com.fasterxml.jackson.databind;
2527

2628
provides AutoStartProvider with FreedesktopAutoStartService;
2729
provides KeychainAccessProvider with GnomeKeyringKeychainAccess, KDEWalletKeychainAccess;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package org.cryptomator.linux.update;
2+
3+
import org.cryptomator.integrations.update.UpdateInfo;
4+
import org.cryptomator.integrations.update.UpdateMechanism;
5+
6+
public record FlatpakUpdateInfo(String version, UpdateMechanism<FlatpakUpdateInfo> updateMechanism) implements UpdateInfo<FlatpakUpdateInfo> {
7+
}

src/main/java/org/cryptomator/linux/update/FlatpakUpdater.java

Lines changed: 49 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package org.cryptomator.linux.update;
22

3+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
4+
import com.fasterxml.jackson.annotation.JsonProperty;
5+
import com.fasterxml.jackson.databind.ObjectMapper;
36
import org.cryptomator.integrations.common.CheckAvailability;
47
import org.cryptomator.integrations.common.DisplayName;
58
import org.cryptomator.integrations.common.OperatingSystem;
6-
import org.cryptomator.integrations.common.Priority;
79
import org.cryptomator.integrations.update.UpdateFailedException;
810
import org.cryptomator.integrations.update.UpdateMechanism;
911
import org.cryptomator.integrations.update.UpdateStep;
@@ -19,21 +21,26 @@
1921
import org.slf4j.LoggerFactory;
2022

2123
import java.io.IOException;
24+
import java.net.URI;
25+
import java.net.http.HttpClient;
26+
import java.net.http.HttpRequest;
27+
import java.net.http.HttpResponse;
2228
import java.util.Collections;
29+
import java.util.Comparator;
2330
import java.util.List;
2431
import java.util.Map;
2532
import java.util.concurrent.CountDownLatch;
2633
import java.util.concurrent.TimeUnit;
27-
import java.util.concurrent.atomic.AtomicBoolean;
2834

29-
@Priority(1000)
3035
@CheckAvailability
3136
@DisplayName("Update via Flatpak update")
3237
@OperatingSystem(OperatingSystem.Value.LINUX)
33-
public class FlatpakUpdater implements UpdateMechanism {
38+
public class FlatpakUpdater implements UpdateMechanism<FlatpakUpdateInfo> {
3439

3540
private static final Logger LOG = LoggerFactory.getLogger(FlatpakUpdater.class);
41+
private static final String FLATHUB_API_BASE_URL = "https://flathub.org/api/v2/appstream/";
3642
private static final String APP_NAME = "org.cryptomator.Cryptomator";
43+
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
3744

3845
private final UpdatePortal portal;
3946

@@ -48,31 +55,50 @@ public boolean isSupported() {
4855
}
4956

5057
@Override
51-
public boolean isUpdateAvailable(String installedVersion) {
52-
var cdl = new CountDownLatch(1);
53-
portal.setUpdateCheckerTaskFor(APP_NAME);
54-
var checkTask = portal.getUpdateCheckerTaskFor(APP_NAME);
55-
var updateAvailable = new AtomicBoolean(false);
56-
checkTask.setOnSucceeded(updateVersion -> {
57-
updateAvailable.set(UpdateMechanism.isUpdateAvailable(updateVersion, installedVersion));
58-
cdl.countDown();
59-
});
60-
checkTask.setOnFailed(error -> {
61-
LOG.warn("Error while checking for updates.", error);
62-
cdl.countDown();
63-
});
58+
public FlatpakUpdateInfo checkForUpdate(String currentVersion, HttpClient httpClient) throws UpdateFailedException {
59+
var uri = URI.create(FLATHUB_API_BASE_URL + APP_NAME);
60+
var request = HttpRequest.newBuilder(uri).GET().build();
6461
try {
65-
cdl.await();
66-
return updateAvailable.get();
62+
var response = httpClient.send(request, HttpResponse.BodyHandlers.ofInputStream());
63+
if (response.statusCode() != 200) {
64+
LOG.warn("GET {} resulted in status {}", uri, response.statusCode());
65+
return null;
66+
} else {
67+
var appstream = OBJECT_MAPPER.reader().readValue(response.body(), AppstreamResponse.class);
68+
var updateVersion = appstream.releases().stream()
69+
.filter(release -> "stable".equalsIgnoreCase(release.type))
70+
.max(Comparator.comparing(AppstreamReleases::timestamp)) // we're interested in the newest stable release
71+
.map(AppstreamReleases::version)
72+
.orElse("0.0.0"); // fallback should always be smaller than current version
73+
if (UpdateMechanism.isUpdateAvailable(updateVersion, currentVersion)) {
74+
return new FlatpakUpdateInfo(updateVersion, this);
75+
} else {
76+
return null;
77+
}
78+
}
79+
} catch (IOException e) {
80+
throw new UpdateFailedException("Check for updates failed.", e);
6781
} catch (InterruptedException e) {
68-
checkTask.cancel();
6982
Thread.currentThread().interrupt();
70-
return false;
83+
LOG.warn("Update check interrupted", e);
84+
return null;
7185
}
7286
}
7387

88+
@JsonIgnoreProperties(ignoreUnknown = true)
89+
public record AppstreamResponse(
90+
@JsonProperty("releases") List<AppstreamReleases> releases
91+
) {}
92+
93+
@JsonIgnoreProperties(ignoreUnknown = true)
94+
public record AppstreamReleases(
95+
@JsonProperty("timestamp") long timestamp,
96+
@JsonProperty("version") String version,
97+
@JsonProperty("type") String type
98+
) {}
99+
74100
@Override
75-
public UpdateStep firstStep() throws UpdateFailedException {
101+
public UpdateStep firstStep(FlatpakUpdateInfo updateInfo) throws UpdateFailedException {
76102
var monitorPath = portal.CreateUpdateMonitor(UpdatePortal.OPTIONS_DUMMY);
77103
if (monitorPath == null) {
78104
throw new UpdateFailedException("Failed to create UpdateMonitor on DBus");
@@ -205,7 +231,7 @@ public UpdateStep applyUpdate() throws IllegalStateException, IOException {
205231
Map<String, Variant<?>> options = UpdatePortal.OPTIONS_DUMMY;
206232
var pid = portal.Spawn(cwdPath, argv, fds, envs, flags, options).longValue();
207233
LOG.info("Spawned updated Cryptomator process with PID {}", pid);
208-
return null;
234+
return UpdateStep.EXIT;
209235
}
210236
}
211237

0 commit comments

Comments
 (0)