diff --git a/airsonic-main/pom.xml b/airsonic-main/pom.xml
index e948a978..c9f077cf 100644
--- a/airsonic-main/pom.xml
+++ b/airsonic-main/pom.xml
@@ -455,6 +455,10 @@
jackson-databind
2.8.7
+
+ com.jayway.jsonpath
+ json-path
+
diff --git a/airsonic-main/src/main/java/org/airsonic/player/service/VersionService.java b/airsonic-main/src/main/java/org/airsonic/player/service/VersionService.java
index 0790126c..4fff3801 100644
--- a/airsonic-main/src/main/java/org/airsonic/player/service/VersionService.java
+++ b/airsonic-main/src/main/java/org/airsonic/player/service/VersionService.java
@@ -19,6 +19,7 @@
*/
package org.airsonic.player.service;
+import com.jayway.jsonpath.JsonPath;
import org.airsonic.player.domain.Version;
import org.apache.commons.io.IOUtils;
import org.apache.http.client.ResponseHandler;
@@ -30,10 +31,18 @@ import org.apache.http.impl.client.HttpClients;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.io.*;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
+import java.util.Comparator;
import java.util.Date;
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.function.Predicate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -64,11 +73,6 @@ public class VersionService {
*/
private static final long LAST_VERSION_FETCH_INTERVAL = 7L * 24L * 3600L * 1000L; // One week
- /**
- * URL from which to fetch latest versions.
- */
- private static final String VERSION_URL = "http://airsonic.org/release/version.txt";
-
/**
* Returns the version number for the locally installed Airsonic version.
*
@@ -217,13 +221,16 @@ public class VersionService {
}
}
+ private final String JSON_PATH = "$..tag_name";
+ private final Pattern VERSION_REGEX = Pattern.compile("^v(.*)");
+ private static final String VERSION_URL = "https://api.github.com/repos/airsonic/airsonic/releases";
+
/**
- * Resolves the latest available Airsonic version by screen-scraping a web page.
- *
- * @throws IOException If an I/O error occurs.
+ * Resolves the latest available Airsonic version by inspecting github.
*/
private void readLatestVersion() throws IOException {
+ LOG.debug("Starting to read latest version");
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(10000)
.setSocketTimeout(10000)
@@ -236,25 +243,25 @@ public class VersionService {
content = client.execute(method, responseHandler);
}
- Pattern finalPattern = Pattern.compile("AIRSONIC_FULL_VERSION_BEGIN(.*)AIRSONIC_FULL_VERSION_END");
- Pattern betaPattern = Pattern.compile("AIRSONIC_BETA_VERSION_BEGIN(.*)AIRSONIC_BETA_VERSION_END");
-
- try (BufferedReader reader = new BufferedReader(new StringReader(content))) {
- String line = reader.readLine();
- while (line != null) {
- Matcher finalMatcher = finalPattern.matcher(line);
- if (finalMatcher.find()) {
- latestFinalVersion = new Version(finalMatcher.group(1));
- LOG.info("Resolved latest Airsonic final version to: " + latestFinalVersion);
- }
- Matcher betaMatcher = betaPattern.matcher(line);
- if (betaMatcher.find()) {
- latestBetaVersion = new Version(betaMatcher.group(1));
- LOG.info("Resolved latest Airsonic beta version to: " + latestBetaVersion);
- }
- line = reader.readLine();
+ List unsortedTags = JsonPath.read(content, JSON_PATH);
+
+ Function convertToVersion = s -> {
+ Matcher match = VERSION_REGEX.matcher(s);
+ if(!match.matches()) {
+ throw new RuntimeException("Unexpected tag format " + s);
}
+ return new Version(match.group(1));
+ };
- }
+ Predicate finalVersionPredicate = version -> !version.isPreview();
+
+ Optional betaV = unsortedTags.stream().map(convertToVersion).sorted(Comparator.reverseOrder()).findFirst();
+ Optional finalV = unsortedTags.stream().map(convertToVersion).sorted(Comparator.reverseOrder()).filter(finalVersionPredicate).findFirst();
+
+ LOG.debug("Got {} for beta version", betaV);
+ LOG.debug("Got {} for final version", finalV);
+
+ latestBetaVersion = betaV.get();
+ latestFinalVersion = finalV.get();
}
}