Little bit of code cleanup

This commit is contained in:
0xb00bface 2020-11-21 20:17:21 +01:00
parent 4f973dbeed
commit 628c92cc67
2 changed files with 112 additions and 175 deletions

View File

@ -1,28 +1,10 @@
package ctbrec.ui;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Type;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.eventbus.Subscribe;
import com.squareup.moshi.JsonAdapter;
import com.squareup.moshi.Moshi;
import com.squareup.moshi.Types;
import ctbrec.Config;
import ctbrec.Model;
import ctbrec.StringUtil;
@ -56,25 +38,14 @@ import ctbrec.sites.stripchat.Stripchat;
import ctbrec.ui.controls.Dialogs;
import ctbrec.ui.news.NewsTab;
import ctbrec.ui.settings.SettingsTab;
import ctbrec.ui.tabs.DonateTabFx;
import ctbrec.ui.tabs.HelpTab;
import ctbrec.ui.tabs.RecordedModelsTab;
import ctbrec.ui.tabs.RecordingsTab;
import ctbrec.ui.tabs.SiteTab;
import ctbrec.ui.tabs.TabSelectionListener;
import ctbrec.ui.tabs.UpdateTab;
import ctbrec.ui.tabs.*;
import ctbrec.ui.tabs.logging.LoggingTab;
import javafx.application.Application;
import javafx.application.HostServices;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Label;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
@ -83,6 +54,17 @@ import javafx.stage.Stage;
import javafx.stage.WindowEvent;
import okhttp3.Request;
import okhttp3.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
public class CamrecApplication extends Application {
@ -92,11 +74,11 @@ public class CamrecApplication extends Application {
private Recorder recorder;
private OnlineMonitor onlineMonitor;
static HostServices hostServices;
private BorderPane rootPane = new BorderPane();
private HBox statusBar = new HBox();
private Label statusLabel = new Label();
private TabPane tabPane = new TabPane();
private List<Site> sites = new ArrayList<>();
private final BorderPane rootPane = new BorderPane();
private final HBox statusBar = new HBox();
private final Label statusLabel = new Label();
private final TabPane tabPane = new TabPane();
private final List<Site> sites = new ArrayList<>();
public static HttpClient httpClient;
public static String title;
private Stage primaryStage;
@ -180,9 +162,8 @@ public class CamrecApplication extends Application {
primaryStage.setScene(scene);
rootPane.setCenter(tabPane);
rootPane.setBottom(statusBar);
for (Iterator<Site> iterator = sites.iterator(); iterator.hasNext();) {
Site site = iterator.next();
if(site.isEnabled()) {
for (Site site : sites) {
if (site.isEnabled()) {
SiteTab siteTab = new SiteTab(site, scene);
tabPane.getTabs().add(siteTab);
}
@ -190,7 +171,7 @@ public class CamrecApplication extends Application {
modelsTab = new RecordedModelsTab("Recording", recorder, sites);
tabPane.getTabs().add(modelsTab);
recordingsTab = new RecordingsTab("Recordings", recorder, config, sites);
recordingsTab = new RecordingsTab("Recordings", recorder, config);
tabPane.getTabs().add(recordingsTab);
tabPane.getTabs().add(new SettingsTab(sites, recorder));
tabPane.getTabs().add(new NewsTab());
@ -215,7 +196,7 @@ public class CamrecApplication extends Application {
.addListener((observable, oldVal, newVal) -> Config.getInstance().getSettings().windowHeight = newVal.intValue());
primaryStage.setMaximized(Config.getInstance().getSettings().windowMaximized);
primaryStage.maximizedProperty()
.addListener((observable, oldVal, newVal) -> Config.getInstance().getSettings().windowMaximized = newVal.booleanValue());
.addListener((observable, oldVal, newVal) -> Config.getInstance().getSettings().windowMaximized = newVal);
Player.scene = primaryStage.getScene();
primaryStage.setX(Config.getInstance().getSettings().windowX);
primaryStage.setY(Config.getInstance().getSettings().windowY);
@ -225,7 +206,7 @@ public class CamrecApplication extends Application {
primaryStage.setOnCloseRequest(createShutdownHandler());
// register changelistener to activate / deactivate tabs, when the user switches between them
tabPane.getSelectionModel().selectedItemProperty().addListener((ChangeListener<Tab>) (ov, from, to) -> {
tabPane.getSelectionModel().selectedItemProperty().addListener((ov, from, to) -> {
if (from instanceof TabSelectionListener) {
((TabSelectionListener) from).deselected();
}
@ -274,44 +255,41 @@ public class CamrecApplication extends Application {
shutdownInfo.show();
final boolean immediately = shutdownNow;
new Thread() {
@Override
public void run() {
modelsTab.saveState();
recordingsTab.saveState();
onlineMonitor.shutdown();
recorder.shutdown(immediately);
for (Site site : sites) {
if(site.isEnabled()) {
site.shutdown();
}
}
try {
Config.getInstance().save();
LOG.info("Shutdown complete. Goodbye!");
Platform.runLater(() -> {
primaryStage.close();
shutdownInfo.close();
Platform.exit();
// This is needed, because OkHttp?! seems to block the shutdown with its writer threads. They are not daemon threads :(
System.exit(0);
});
} catch (IOException e1) {
Platform.runLater(() -> {
Alert alert = new AutosizeAlert(Alert.AlertType.ERROR, primaryStage.getScene());
alert.setTitle("Error saving settings");
alert.setContentText("Couldn't save settings: " + e1.getLocalizedMessage());
alert.showAndWait();
System.exit(1);
});
}
try {
ExternalBrowser.getInstance().close();
} catch (IOException e) {
// noop
new Thread(() -> {
modelsTab.saveState();
recordingsTab.saveState();
onlineMonitor.shutdown();
recorder.shutdown(immediately);
for (Site site : sites) {
if (site.isEnabled()) {
site.shutdown();
}
}
}.start();
try {
Config.getInstance().save();
LOG.info("Shutdown complete. Goodbye!");
Platform.runLater(() -> {
primaryStage.close();
shutdownInfo.close();
Platform.exit();
// This is needed, because OkHttp?! seems to block the shutdown with its writer threads. They are not daemon threads :(
System.exit(0);
});
} catch (IOException e1) {
Platform.runLater(() -> {
Alert alert = new AutosizeAlert(Alert.AlertType.ERROR, primaryStage.getScene());
alert.setTitle("Error saving settings");
alert.setContentText("Couldn't save settings: " + e1.getLocalizedMessage());
alert.showAndWait();
System.exit(1);
});
}
try {
ExternalBrowser.getInstance().close();
} catch (IOException e12) {
// noop
}
}).start();
};
}
@ -355,8 +333,8 @@ public class CamrecApplication extends Application {
if (activeRecordings == 0) {
bytesPerSecond = 0;
}
String humanreadable = ByteUnitFormatter.format(bytesPerSecond);
String status = String.format("Recording %s / %s models @ %s/s", activeRecordings, recorder.getModels().size(), humanreadable);
String humanReadable = ByteUnitFormatter.format(bytesPerSecond);
String status = String.format("Recording %s / %s models @ %s/s", activeRecordings, recorder.getModels().size(), humanReadable);
Platform.runLater(() -> statusLabel.setText(status));
}
@ -370,7 +348,7 @@ public class CamrecApplication extends Application {
" -fx-focus-color: -fx-accent;\n" +
" -fx-control-inner-background-alt: derive(-fx-base, 95%);\n" +
"}";
fos.write(content.getBytes("utf-8"));
fos.write(content.getBytes(StandardCharsets.UTF_8));
} catch(Exception e) {
LOG.error("Couldn't write stylesheet for user defined color theme");
}
@ -400,7 +378,6 @@ public class CamrecApplication extends Application {
private void createRecorder() {
if (config.getSettings().localRecording) {
//recorder = new LocalRecorder(config);
try {
recorder = new NextGenLocalRecorder(config, sites);
} catch (IOException e) {
@ -431,7 +408,7 @@ public class CamrecApplication extends Application {
private void createHttpClient() {
httpClient = new HttpClient("camrec") {
@Override
public boolean login() throws IOException {
public boolean login() {
return false;
}
};
@ -481,8 +458,7 @@ public class CamrecApplication extends Application {
try (InputStream is = CamrecApplication.class.getClassLoader().getResourceAsStream("version")) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String versionString = reader.readLine();
Version version = Version.of(versionString);
return version;
return Version.of(versionString);
}
}
}

View File

@ -1,33 +1,5 @@
package ctbrec.ui.tabs;
import static ctbrec.Recording.State.*;
import static javafx.scene.control.ButtonType.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.nio.file.NoSuchFileException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.DecimalFormat;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ctbrec.Config;
import ctbrec.Model;
import ctbrec.Recording;
@ -40,13 +12,7 @@ import ctbrec.recorder.ProgressListener;
import ctbrec.recorder.Recorder;
import ctbrec.recorder.RecordingPinnedException;
import ctbrec.recorder.download.hls.MergedFfmpegHlsDownload;
import ctbrec.sites.Site;
import ctbrec.ui.AutosizeAlert;
import ctbrec.ui.CamrecApplication;
import ctbrec.ui.DesktopIntegration;
import ctbrec.ui.FileDownload;
import ctbrec.ui.JavaFxRecording;
import ctbrec.ui.Player;
import ctbrec.ui.*;
import ctbrec.ui.action.FollowAction;
import ctbrec.ui.action.PauseAction;
import ctbrec.ui.action.StopRecordingAction;
@ -64,24 +30,9 @@ import javafx.geometry.Insets;
import javafx.scene.Cursor;
import javafx.scene.Node;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.ButtonType;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.Tab;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.*;
import javafx.scene.control.TableColumn.SortType;
import javafx.scene.control.TableView;
import javafx.scene.control.Tooltip;
import javafx.scene.input.ContextMenuEvent;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.*;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.HBox;
@ -89,6 +40,29 @@ import javafx.scene.layout.StackPane;
import javafx.scene.text.Font;
import javafx.stage.FileChooser;
import javafx.util.Duration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.nio.file.NoSuchFileException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.DecimalFormat;
import java.time.Instant;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
import static ctbrec.Recording.State.*;
import static javafx.scene.control.ButtonType.NO;
import static javafx.scene.control.ButtonType.YES;
public class RecordingsTab extends Tab implements TabSelectionListener {
private static final String ERROR_WHILE_DOWNLOADING_RECORDING = "Error while downloading recording";
@ -96,10 +70,8 @@ public class RecordingsTab extends Tab implements TabSelectionListener {
private static final Logger LOG = LoggerFactory.getLogger(RecordingsTab.class);
private ScheduledService<List<JavaFxRecording>> updateService;
private Config config;
private Recorder recorder;
@SuppressWarnings("unused")
private List<Site> sites;
private final Config config;
private final Recorder recorder;
private long spaceTotal = -1;
private long spaceFree = -1;
@ -112,11 +84,10 @@ public class RecordingsTab extends Tab implements TabSelectionListener {
Label spaceLabel;
Lock recordingsLock = new ReentrantLock();
public RecordingsTab(String title, Recorder recorder, Config config, List<Site> sites) {
public RecordingsTab(String title, Recorder recorder, Config config) {
super(title);
this.recorder = recorder;
this.config = config;
this.sites = sites;
createGui();
setClosable(false);
initializeUpdateService();
@ -143,9 +114,9 @@ public class RecordingsTab extends Tab implements TabSelectionListener {
date.setId("date");
date.setCellValueFactory(cdf -> {
Instant instant = cdf.getValue().getStartDate();
return new SimpleObjectProperty<Instant>(instant);
return new SimpleObjectProperty<>(instant);
});
date.setCellFactory(new DateTimeCellFactory<JavaFxRecording>());
date.setCellFactory(new DateTimeCellFactory<>());
date.setPrefWidth(200);
TableColumn<JavaFxRecording, String> status = new TableColumn<>("Status");
status.setId("status");
@ -200,7 +171,7 @@ public class RecordingsTab extends Tab implements TabSelectionListener {
}
private TableCell<JavaFxRecording, Number> createSizeCell() {
TableCell<JavaFxRecording, Number> cell = new TableCell<JavaFxRecording, Number>() {
return new TableCell<>() {
@Override
protected void updateItem(Number sizeInByte, boolean empty) {
if (empty || sizeInByte == null) {
@ -219,7 +190,6 @@ public class RecordingsTab extends Tab implements TabSelectionListener {
}
}
};
return cell;
}
private void onContextMenuRequested(ContextMenuEvent event) {
@ -276,7 +246,7 @@ public class RecordingsTab extends Tab implements TabSelectionListener {
AutosizeAlert autosizeAlert = new AutosizeAlert(AlertType.ERROR, getTabPane().getScene());
autosizeAlert.setTitle("Whoopsie!");
autosizeAlert.setHeaderText("Recordings not available");
autosizeAlert.setContentText("An error occured while retrieving the list of recordings");
autosizeAlert.setContentText("An error occurred while retrieving the list of recordings");
autosizeAlert.showAndWait();
});
}
@ -302,13 +272,9 @@ public class RecordingsTab extends Tab implements TabSelectionListener {
recordingsLock.lock();
try {
for (Iterator<JavaFxRecording> iterator = observableRecordings.iterator(); iterator.hasNext();) {
JavaFxRecording old = iterator.next();
if (!recordings.contains(old)) {
// remove deleted recordings
iterator.remove();
}
}
// remove deleted recordings
observableRecordings.removeIf(old -> !recordings.contains(old));
for (JavaFxRecording recording : recordings) {
if (!observableRecordings.contains(recording)) {
// add new recordings
@ -327,10 +293,10 @@ public class RecordingsTab extends Tab implements TabSelectionListener {
}
private ScheduledService<List<JavaFxRecording>> createUpdateService() {
ScheduledService<List<JavaFxRecording>> service = new ScheduledService<List<JavaFxRecording>>() {
ScheduledService<List<JavaFxRecording>> service = new ScheduledService<>() {
@Override
protected Task<List<JavaFxRecording>> createTask() {
return new Task<List<JavaFxRecording>>() {
return new Task<>() {
@Override
public List<JavaFxRecording> call() throws IOException, InvalidKeyException, NoSuchAlgorithmException {
updateSpace();
@ -401,13 +367,13 @@ public class RecordingsTab extends Tab implements TabSelectionListener {
contextMenu.getItems().add(openContactSheet);
MenuItem stopRecording = new MenuItem("Stop Recording");
stopRecording.setOnAction(e -> stopRecording(recordings.stream().map(r -> r.getModel()).collect(Collectors.toList())));
stopRecording.setOnAction(e -> stopRecording(recordings.stream().map(JavaFxRecording::getModel).collect(Collectors.toList())));
if (recordings.stream().anyMatch(r -> r.getStatus() == RECORDING)) {
contextMenu.getItems().add(stopRecording);
}
MenuItem pauseRecording = new MenuItem("Pause Recording");
pauseRecording.setOnAction(e -> pauseRecording(recordings.stream().map(r -> r.getModel()).collect(Collectors.toList())));
pauseRecording.setOnAction(e -> pauseRecording(recordings.stream().map(JavaFxRecording::getModel).collect(Collectors.toList())));
if (recordings.stream().anyMatch(r -> r.getStatus() == RECORDING)) {
contextMenu.getItems().add(pauseRecording);
}
@ -420,8 +386,8 @@ public class RecordingsTab extends Tab implements TabSelectionListener {
}
MenuItem followModels = new MenuItem("Follow Model");
followModels.setOnAction(e -> follow(recordings.stream().map(r -> r.getModel()).collect(Collectors.toList())));
followModels.setDisable(!recordings.stream().map(r -> r.getModel()).allMatch(m -> m.getSite().supportsFollow() && m.getSite().credentialsAvailable()));
followModels.setOnAction(e -> follow(recordings.stream().map(JavaFxRecording::getModel).collect(Collectors.toList())));
followModels.setDisable(!recordings.stream().map(JavaFxRecording::getModel).allMatch(m -> m.getSite().supportsFollow() && m.getSite().credentialsAvailable()));
contextMenu.getItems().add(followModels);
MenuItem openDir = new MenuItem("Open directory");
@ -484,7 +450,7 @@ public class RecordingsTab extends Tab implements TabSelectionListener {
try {
target = File.createTempFile("cs_", ".jpg");
target.deleteOnExit();
FileDownload download = new FileDownload(CamrecApplication.httpClient, (p) -> {
FileDownload download = new FileDownload(CamrecApplication.httpClient, p -> {
if (p == 100) {
DesktopIntegration.open(target);
}
@ -653,8 +619,7 @@ public class RecordingsTab extends Tab implements TabSelectionListener {
} else {
String downloadFilename = config.getSettings().downloadFilename;
String fileSuffix = config.getSettings().ffmpegFileSuffix;
String filename = new DownloadPostprocessor().fillInPlaceHolders(downloadFilename, recording, config) + '.' + fileSuffix;
return filename;
return new DownloadPostprocessor().fillInPlaceHolders(downloadFilename, recording, config) + '.' + fileSuffix;
}
}
@ -716,7 +681,7 @@ public class RecordingsTab extends Tab implements TabSelectionListener {
AutosizeAlert autosizeAlert = new AutosizeAlert(AlertType.ERROR, getTabPane().getScene());
autosizeAlert.setTitle(title);
autosizeAlert.setHeaderText(msg);
StringBuilder contentText = new StringBuilder("On or more error(s) occured:");
StringBuilder contentText = new StringBuilder("On or more error(s) occurred:");
for (Exception exception : exceptions) {
contentText.append("\n• ").append(exception.getLocalizedMessage());
}
@ -726,15 +691,12 @@ public class RecordingsTab extends Tab implements TabSelectionListener {
}
private void play(Recording recording) {
new Thread() {
@Override
public void run() {
boolean started = Player.play(recording);
if (started && Config.getInstance().getSettings().showPlayerStarting) {
Platform.runLater(() -> Toast.makeText(getTabPane().getScene(), "Starting Player", 2000, 500, 500));
}
new Thread(() -> {
boolean started = Player.play(recording);
if (started && Config.getInstance().getSettings().showPlayerStarting) {
Platform.runLater(() -> Toast.makeText(getTabPane().getScene(), "Starting Player", 2000, 500, 500));
}
}.start();
}).start();
}
private void delete(List<JavaFxRecording> recordings) {
@ -764,8 +726,7 @@ public class RecordingsTab extends Tab implements TabSelectionListener {
try {
List<Recording> deleted = new ArrayList<>();
List<Exception> exceptions = new ArrayList<>();
for (Iterator<JavaFxRecording> iterator = recordings.iterator(); iterator.hasNext();) {
JavaFxRecording r = iterator.next();
for (JavaFxRecording r : recordings) {
if (r.getStatus() != FINISHED && r.getStatus() != FAILED && r.getStatus() != WAITING) {
continue;
}