Add update check
Add update check, which checks the github API to retrieve the latest version and opens a tab, if new update is available.
This commit is contained in:
parent
4c32dc84f5
commit
32e060ceb2
20
pom.xml
20
pom.xml
|
@ -15,6 +15,19 @@
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/resources</directory>
|
||||||
|
<filtering>false</filtering>
|
||||||
|
</resource>
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/resources</directory>
|
||||||
|
<filtering>true</filtering>
|
||||||
|
<includes>
|
||||||
|
<include>version</include>
|
||||||
|
</includes>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<artifactId>maven-assembly-plugin</artifactId>
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
@ -156,5 +169,12 @@
|
||||||
<artifactId>jcodec</artifactId>
|
<artifactId>jcodec</artifactId>
|
||||||
<version>0.2.3</version>
|
<version>0.2.3</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.12</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
package ctbrec;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class Version implements Comparable<Version> {
|
||||||
|
int major = 0;
|
||||||
|
int minor = 0;
|
||||||
|
int revision = 0;
|
||||||
|
String designator = "";
|
||||||
|
|
||||||
|
public static Version of(String s) {
|
||||||
|
Pattern p = Pattern.compile("(\\d+)\\.(\\d+)\\.(\\d+)(?:-(.+))?");
|
||||||
|
Matcher m = p.matcher(s);
|
||||||
|
if(m.matches()) {
|
||||||
|
Version v = new Version();
|
||||||
|
v.major = Integer.parseInt(m.group(1));
|
||||||
|
v.minor = Integer.parseInt(m.group(2));
|
||||||
|
v.revision = Integer.parseInt(m.group(3));
|
||||||
|
if(m.group(4) != null) {
|
||||||
|
v.designator = m.group(4);
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Version format has to be x.x.x");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMajor() {
|
||||||
|
return major;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMinor() {
|
||||||
|
return minor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRevision() {
|
||||||
|
return revision;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDesignator() {
|
||||||
|
return designator;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
String version = major + "." + minor + "." + revision;
|
||||||
|
if(!designator.isEmpty()) {
|
||||||
|
version += "-" + designator;
|
||||||
|
}
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((designator == null) ? 0 : designator.hashCode());
|
||||||
|
result = prime * result + major;
|
||||||
|
result = prime * result + minor;
|
||||||
|
result = prime * result + revision;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
Version other = (Version) obj;
|
||||||
|
if (designator == null) {
|
||||||
|
if (other.designator != null)
|
||||||
|
return false;
|
||||||
|
} else if (!designator.equals(other.designator))
|
||||||
|
return false;
|
||||||
|
if (major != other.major)
|
||||||
|
return false;
|
||||||
|
if (minor != other.minor)
|
||||||
|
return false;
|
||||||
|
if (revision != other.revision)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(Version o) {
|
||||||
|
int result = 0;
|
||||||
|
if(major == o.major) {
|
||||||
|
if(minor == o.minor) {
|
||||||
|
if(revision == o.revision) {
|
||||||
|
if(!designator.isEmpty() && o.designator.isEmpty()) {
|
||||||
|
result = -1;
|
||||||
|
} else if(designator.isEmpty() && !o.designator.isEmpty()) {
|
||||||
|
result = 1;
|
||||||
|
} else {
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result = revision - o.revision;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result = minor - o.minor;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result = major - o.major;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,14 +1,23 @@
|
||||||
package ctbrec.ui;
|
package ctbrec.ui;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.squareup.moshi.JsonAdapter;
|
||||||
|
import com.squareup.moshi.Moshi;
|
||||||
|
import com.squareup.moshi.Types;
|
||||||
|
|
||||||
import ctbrec.Config;
|
import ctbrec.Config;
|
||||||
import ctbrec.HttpClient;
|
import ctbrec.HttpClient;
|
||||||
|
import ctbrec.Version;
|
||||||
import ctbrec.recorder.LocalRecorder;
|
import ctbrec.recorder.LocalRecorder;
|
||||||
import ctbrec.recorder.Recorder;
|
import ctbrec.recorder.Recorder;
|
||||||
import ctbrec.recorder.RemoteRecorder;
|
import ctbrec.recorder.RemoteRecorder;
|
||||||
|
@ -24,57 +33,39 @@ import javafx.scene.control.TabPane;
|
||||||
import javafx.scene.control.TabPane.TabClosingPolicy;
|
import javafx.scene.control.TabPane.TabClosingPolicy;
|
||||||
import javafx.scene.image.Image;
|
import javafx.scene.image.Image;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
|
import okhttp3.Request;
|
||||||
|
import okhttp3.Response;
|
||||||
|
|
||||||
public class Launcher extends Application {
|
public class Launcher extends Application {
|
||||||
|
|
||||||
private static final transient Logger LOG = LoggerFactory.getLogger(Launcher.class);
|
private static final transient Logger LOG = LoggerFactory.getLogger(Launcher.class);
|
||||||
public static final String BASE_URI = "https://chaturbate.com";
|
public static final String BASE_URI = "https://chaturbate.com";
|
||||||
|
|
||||||
|
private Config config;
|
||||||
private Recorder recorder;
|
private Recorder recorder;
|
||||||
private HttpClient client;
|
private HttpClient client;
|
||||||
private static HostServices hostServices;
|
private static HostServices hostServices;
|
||||||
private SettingsTab settingsTab;
|
private SettingsTab settingsTab;
|
||||||
|
private TabPane tabPane = new TabPane();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start(Stage primaryStage) throws Exception {
|
public void start(Stage primaryStage) throws Exception {
|
||||||
try {
|
loadConfig();
|
||||||
Config.init();
|
|
||||||
} catch (Exception e) {
|
|
||||||
Alert alert = new AutosizeAlert(Alert.AlertType.ERROR);
|
|
||||||
alert.setTitle("Whoopsie");
|
|
||||||
alert.setContentText("Couldn't load settings.");
|
|
||||||
alert.showAndWait();
|
|
||||||
System.exit(1);
|
|
||||||
}
|
|
||||||
hostServices = getHostServices();
|
hostServices = getHostServices();
|
||||||
Config config = Config.getInstance();
|
|
||||||
client = HttpClient.getInstance();
|
client = HttpClient.getInstance();
|
||||||
if(config.getSettings().localRecording) {
|
createRecorder();
|
||||||
recorder = new LocalRecorder(config);
|
doInitialLogin();
|
||||||
} else {
|
createGui(primaryStage);
|
||||||
recorder = new RemoteRecorder(config, client);
|
checkForUpdates();
|
||||||
}
|
|
||||||
if(config.getSettings().username != null && !config.getSettings().username.isEmpty()) {
|
|
||||||
new Thread() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if(!Objects.equals(System.getenv("CTBREC_DEV"), "1")) {
|
|
||||||
try {
|
|
||||||
client.login();
|
|
||||||
} catch (IOException e1) {
|
|
||||||
LOG.warn("Initial login failed" , e1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void createGui(Stage primaryStage) {
|
||||||
LOG.debug("Creating GUI");
|
LOG.debug("Creating GUI");
|
||||||
primaryStage.setTitle("CTB Recorder");
|
primaryStage.setTitle("CTB Recorder");
|
||||||
InputStream icon = getClass().getResourceAsStream("/icon.png");
|
InputStream icon = getClass().getResourceAsStream("/icon.png");
|
||||||
primaryStage.getIcons().add(new Image(icon));
|
primaryStage.getIcons().add(new Image(icon));
|
||||||
TabPane root = new TabPane();
|
tabPane = new TabPane();
|
||||||
root.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Tab>() {
|
tabPane.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Tab>() {
|
||||||
@Override
|
@Override
|
||||||
public void changed(ObservableValue<? extends Tab> ov, Tab from, Tab to) {
|
public void changed(ObservableValue<? extends Tab> ov, Tab from, Tab to) {
|
||||||
if(from != null && from instanceof TabSelectionListener) {
|
if(from != null && from instanceof TabSelectionListener) {
|
||||||
|
@ -85,24 +76,24 @@ public class Launcher extends Application {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
root.setTabClosingPolicy(TabClosingPolicy.SELECTED_TAB);
|
tabPane.setTabClosingPolicy(TabClosingPolicy.SELECTED_TAB);
|
||||||
root.getTabs().add(createTab("Featured", BASE_URI + "/"));
|
tabPane.getTabs().add(createTab("Featured", BASE_URI + "/"));
|
||||||
root.getTabs().add(createTab("Female", BASE_URI + "/female-cams/"));
|
tabPane.getTabs().add(createTab("Female", BASE_URI + "/female-cams/"));
|
||||||
root.getTabs().add(createTab("Male", BASE_URI + "/male-cams/"));
|
tabPane.getTabs().add(createTab("Male", BASE_URI + "/male-cams/"));
|
||||||
root.getTabs().add(createTab("Couples", BASE_URI + "/couple-cams/"));
|
tabPane.getTabs().add(createTab("Couples", BASE_URI + "/couple-cams/"));
|
||||||
root.getTabs().add(createTab("Trans", BASE_URI + "/trans-cams/"));
|
tabPane.getTabs().add(createTab("Trans", BASE_URI + "/trans-cams/"));
|
||||||
FollowedTab tab = new FollowedTab("Followed", BASE_URI + "/followed-cams/");
|
FollowedTab tab = new FollowedTab("Followed", BASE_URI + "/followed-cams/");
|
||||||
tab.setRecorder(recorder);
|
tab.setRecorder(recorder);
|
||||||
root.getTabs().add(tab);
|
tabPane.getTabs().add(tab);
|
||||||
RecordedModelsTab modelsTab = new RecordedModelsTab("Recording", recorder);
|
RecordedModelsTab modelsTab = new RecordedModelsTab("Recording", recorder);
|
||||||
root.getTabs().add(modelsTab);
|
tabPane.getTabs().add(modelsTab);
|
||||||
RecordingsTab recordingsTab = new RecordingsTab("Recordings", recorder, config);
|
RecordingsTab recordingsTab = new RecordingsTab("Recordings", recorder, config);
|
||||||
root.getTabs().add(recordingsTab);
|
tabPane.getTabs().add(recordingsTab);
|
||||||
settingsTab = new SettingsTab();
|
settingsTab = new SettingsTab();
|
||||||
root.getTabs().add(settingsTab);
|
tabPane.getTabs().add(settingsTab);
|
||||||
root.getTabs().add(new DonateTabFx());
|
tabPane.getTabs().add(new DonateTabFx());
|
||||||
|
|
||||||
primaryStage.setScene(new Scene(root, 1340, 800));
|
primaryStage.setScene(new Scene(tabPane, 1340, 800));
|
||||||
primaryStage.show();
|
primaryStage.show();
|
||||||
primaryStage.setOnCloseRequest((e) -> {
|
primaryStage.setOnCloseRequest((e) -> {
|
||||||
e.consume();
|
e.consume();
|
||||||
|
@ -137,6 +128,44 @@ public class Launcher extends Application {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void doInitialLogin() {
|
||||||
|
if(config.getSettings().username != null && !config.getSettings().username.isEmpty()) {
|
||||||
|
new Thread() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if(!Objects.equals(System.getenv("CTBREC_DEV"), "1")) {
|
||||||
|
try {
|
||||||
|
client.login();
|
||||||
|
} catch (IOException e1) {
|
||||||
|
LOG.warn("Initial login failed" , e1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createRecorder() {
|
||||||
|
if(config.getSettings().localRecording) {
|
||||||
|
recorder = new LocalRecorder(config);
|
||||||
|
} else {
|
||||||
|
recorder = new RemoteRecorder(config, client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadConfig() {
|
||||||
|
try {
|
||||||
|
Config.init();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Alert alert = new AutosizeAlert(Alert.AlertType.ERROR);
|
||||||
|
alert.setTitle("Whoopsie");
|
||||||
|
alert.setContentText("Couldn't load settings.");
|
||||||
|
alert.showAndWait();
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
config = Config.getInstance();
|
||||||
|
}
|
||||||
|
|
||||||
Tab createTab(String title, String url) {
|
Tab createTab(String title, String url) {
|
||||||
ThumbOverviewTab tab = new ThumbOverviewTab(title, url, false);
|
ThumbOverviewTab tab = new ThumbOverviewTab(title, url, false);
|
||||||
tab.setRecorder(recorder);
|
tab.setRecorder(recorder);
|
||||||
|
@ -150,4 +179,82 @@ public class Launcher extends Application {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
launch(args);
|
launch(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkForUpdates() {
|
||||||
|
Thread updateCheck = new Thread(() -> {
|
||||||
|
try {
|
||||||
|
String url = "https://api.github.com/repos/0xboobface/ctbrec/releases";
|
||||||
|
Request request = new Request.Builder().url(url).build();
|
||||||
|
Response response = client.execute(request);
|
||||||
|
if(response.isSuccessful()) {
|
||||||
|
Moshi moshi = new Moshi.Builder().build();
|
||||||
|
Type type = Types.newParameterizedType(List.class, Release.class);
|
||||||
|
JsonAdapter<List<Release>> adapter = moshi.adapter(type);
|
||||||
|
List<Release> releases = adapter.fromJson(response.body().source());
|
||||||
|
Release latest = releases.get(0);
|
||||||
|
Version latestVersion = latest.getVersion();
|
||||||
|
Version ctbrecVersion = getVersion();
|
||||||
|
if(latestVersion.compareTo(ctbrecVersion) > 0) {
|
||||||
|
LOG.debug("Update available {} < {}", ctbrecVersion, latestVersion);
|
||||||
|
Platform.runLater(() -> tabPane.getTabs().add(new UpdateTab(latest)));
|
||||||
|
} else {
|
||||||
|
LOG.debug("ctbrec is up-to-date {}", ctbrecVersion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.warn("Update check failed {}", e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
updateCheck.setName("Update Check");
|
||||||
|
updateCheck.setDaemon(true);
|
||||||
|
updateCheck.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Version getVersion() throws IOException {
|
||||||
|
if(Objects.equals(System.getenv("CTBREC_DEV"), "1")) {
|
||||||
|
return Version.of("0.0.0");
|
||||||
|
} else {
|
||||||
|
try(InputStream is = getClass().getClassLoader().getResourceAsStream("version")) {
|
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
|
||||||
|
String versionString = reader.readLine();
|
||||||
|
Version version = Version.of(versionString);
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Release {
|
||||||
|
private String name;
|
||||||
|
private String tag_name;
|
||||||
|
private String html_url;
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTagName() {
|
||||||
|
return tag_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTagName(String tagName) {
|
||||||
|
this.tag_name = tagName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHtmlUrl() {
|
||||||
|
return html_url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHtmlUrl(String htmlUrl) {
|
||||||
|
this.html_url = htmlUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Version getVersion() {
|
||||||
|
return Version.of(tag_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
package ctbrec.ui;
|
||||||
|
|
||||||
|
import ctbrec.ui.Launcher.Release;
|
||||||
|
import javafx.geometry.Pos;
|
||||||
|
import javafx.scene.control.Button;
|
||||||
|
import javafx.scene.control.Label;
|
||||||
|
import javafx.scene.control.Tab;
|
||||||
|
import javafx.scene.layout.VBox;
|
||||||
|
|
||||||
|
public class UpdateTab extends Tab {
|
||||||
|
public UpdateTab(Release latest) {
|
||||||
|
setText("Update Available");
|
||||||
|
VBox vbox = new VBox(10);
|
||||||
|
vbox.getChildren().add(new Label("New Version available " + latest.getVersion()));
|
||||||
|
Button button = new Button("Download");
|
||||||
|
button.setOnAction((e) -> Launcher.open(latest.getHtmlUrl()));
|
||||||
|
vbox.getChildren().add(button);
|
||||||
|
vbox.setAlignment(Pos.CENTER);
|
||||||
|
setContent(vbox);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
${project.version}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package ctbrec;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class VersionTest {
|
||||||
|
@Test
|
||||||
|
public void testOf() {
|
||||||
|
Version v = Version.of("1.0.0");
|
||||||
|
assertEquals(1, v.major);
|
||||||
|
assertEquals(0, v.minor);
|
||||||
|
assertEquals(0, v.revision);
|
||||||
|
|
||||||
|
v = Version.of("12.123.1234");
|
||||||
|
assertEquals(12, v.major);
|
||||||
|
assertEquals(123, v.minor);
|
||||||
|
assertEquals(1234, v.revision);
|
||||||
|
|
||||||
|
v = Version.of("1.0.0-SNAPSHOT");
|
||||||
|
assertEquals(1, v.major);
|
||||||
|
assertEquals(0, v.minor);
|
||||||
|
assertEquals(0, v.revision);
|
||||||
|
assertEquals("SNAPSHOT", v.designator);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCompareTo() {
|
||||||
|
Version a = Version.of("1.0.0");
|
||||||
|
Version b = Version.of("1.0.0");
|
||||||
|
assertEquals(0, a.compareTo(b));
|
||||||
|
|
||||||
|
a = Version.of("1.0.0");
|
||||||
|
b = Version.of("1.0.1");
|
||||||
|
assertEquals(-1, a.compareTo(b));
|
||||||
|
|
||||||
|
a = Version.of("1.0.0");
|
||||||
|
b = Version.of("1.1.0");
|
||||||
|
assertEquals(-1, a.compareTo(b));
|
||||||
|
|
||||||
|
a = Version.of("1.0.0");
|
||||||
|
b = Version.of("2.0.0");
|
||||||
|
assertEquals(-1, a.compareTo(b));
|
||||||
|
|
||||||
|
a = Version.of("1.0.0-SNAPSHOT");
|
||||||
|
b = Version.of("1.0.0");
|
||||||
|
assertEquals(-1, a.compareTo(b));
|
||||||
|
|
||||||
|
a = Version.of("1.0.0-beta1");
|
||||||
|
b = Version.of("1.0.0");
|
||||||
|
assertEquals(-1, a.compareTo(b));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue