Code cleanup

This commit is contained in:
0xb00bface 2021-05-14 19:52:46 +02:00
parent 7d23ebccfe
commit ea062582d4
135 changed files with 1869 additions and 1948 deletions

View File

@ -11,11 +11,7 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-15">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-15"/>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>

View File

@ -12,5 +12,5 @@ org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.release=enabled
org.eclipse.jdt.core.compiler.source=15

View File

@ -1,5 +1,7 @@
package ctbrec.docs;
import static java.nio.charset.StandardCharsets.*;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
@ -7,7 +9,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@ -32,13 +33,13 @@ public abstract class AbstractDocServlet extends HttpServlet {
if(resourceAsStream == null) {
throw new FileNotFoundException();
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
int length = 0;
byte[] buffer = new byte[1024];
var out = new ByteArrayOutputStream();
var length = 0;
var buffer = new byte[1024];
while( (length = resourceAsStream.read(buffer)) >= 0 ) {
out.write(buffer, 0, length);
}
return new String(out.toByteArray(), "utf-8");
return new String(out.toByteArray(), UTF_8);
}
String getHeader() throws IOException {
@ -66,15 +67,15 @@ public abstract class AbstractDocServlet extends HttpServlet {
private void indexJar(URL resource, List<String> pages) throws IOException {
String fileUrl = resource.getFile();
fileUrl = URLDecoder.decode(fileUrl, StandardCharsets.UTF_8);
fileUrl = URLDecoder.decode(fileUrl, UTF_8);
int colon = fileUrl.indexOf(':');
int exclamation = fileUrl.indexOf('!');
String jar = fileUrl.substring(colon + 1, exclamation);
String internalFile = fileUrl.substring(exclamation + 2);
try (JarFile jarFile = new JarFile(jar)) {
var jar = fileUrl.substring(colon + 1, exclamation);
var internalFile = fileUrl.substring(exclamation + 2);
try (var jarFile = new JarFile(jar)) {
Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry jarEntry = entries.nextElement();
var jarEntry = entries.nextElement();
String name = jarEntry.getName();
if (name.startsWith(internalFile) && name.toLowerCase().endsWith(".md")) {
pages.add(name.substring(name.lastIndexOf('/') + 1));
@ -84,7 +85,7 @@ public abstract class AbstractDocServlet extends HttpServlet {
}
private void indexDirectory(URL resource, List<String> pages) {
File docs = new File(resource.getFile());
var docs = new File(resource.getFile());
String[] files = docs.list((dir, name) -> name.toLowerCase().endsWith(".md"));
pages.addAll(Arrays.asList(files));
}
@ -94,15 +95,19 @@ public abstract class AbstractDocServlet extends HttpServlet {
return loadFile(resource);
}
protected void error(HttpServletResponse resp, int status, String message) throws IOException {
resp.setStatus(status);
resp.getWriter().println(getHeader());
String html = loadFile("/html/docs/" + status + ".html");
if(message == null || message.trim().isEmpty()) {
message = "";
protected void error(HttpServletResponse resp, int status, String message) {
try {
resp.setStatus(status);
resp.getWriter().println(getHeader());
String html = loadFile("/html/docs/" + status + ".html");
if(message == null || message.trim().isEmpty()) {
message = "";
}
html = html.replace("{message}", message);
resp.getWriter().println(html);
resp.getWriter().println(getFooter());
} catch (IOException e) {
LOG.error("Error while sending error response. Man, his is bad!", e);
}
html = html.replace("{message}", message);
resp.getWriter().println(html);
resp.getWriter().println(getFooter());
}
}

View File

@ -16,40 +16,41 @@ import org.slf4j.LoggerFactory;
import ctbrec.servlet.StaticFileServlet;
public class DocServer {
private static final transient Logger LOG = LoggerFactory.getLogger(DocServer.class);
private static final Logger LOG = LoggerFactory.getLogger(DocServer.class);
private static Server server = new Server();
private static volatile boolean started = false;
public synchronized static void start() throws Exception {
private DocServer() {}
public static synchronized void start() throws Exception {
if(started) {
return;
}
started = true;
server = new Server();
var server = new Server();
HttpConfiguration config = new HttpConfiguration();
var config = new HttpConfiguration();
config.setSendServerVersion(false);
ServerConnector http = new ServerConnector(server, new HttpConnectionFactory(config));
var http = new ServerConnector(server, new HttpConnectionFactory(config));
http.setPort(5689);
server.addConnector(http);
ServletHandler handler = new ServletHandler();
var handler = new ServletHandler();
server.setHandler(handler);
HandlerList handlers = new HandlerList();
var handlers = new HandlerList();
handlers.setHandlers(new Handler[] { handler });
server.setHandler(handlers);
MarkdownServlet markdownServlet = new MarkdownServlet();
ServletHolder holder = new ServletHolder(markdownServlet);
var markdownServlet = new MarkdownServlet();
var holder = new ServletHolder(markdownServlet);
handler.addServletWithMapping(holder, "/docs/*");
AbstractDocServlet searchServlet = new SearchServlet();
holder = new ServletHolder(searchServlet);
handler.addServletWithMapping(holder, "/search/*");
StaticFileServlet staticFileServlet = new StaticFileServlet("/html", false);
var staticFileServlet = new StaticFileServlet("/html", false);
holder = new ServletHolder(staticFileServlet);
handler.addServletWithMapping(holder, "/static/*");

View File

@ -38,16 +38,18 @@ public class MarkdownServlet extends AbstractDocServlet {
}
} catch (FileNotFoundException e) {
error(resp, HttpServletResponse.SC_NOT_FOUND, "");
} catch (Exception e) {
error(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "");
}
}
private void listPages(HttpServletResponse resp) throws IOException {
List<String> pages = getPages();
String html = "<ul>";
var html = new StringBuilder("<ul>");
for (String page : pages) {
html += "<li><a href=\"/docs/" + page + "\">" + page + "</a></li>";
html.append("<li><a href=\"/docs/").append(page).append("\">").append(page).append("</a></li>");
}
html += "</ul>";
html.append("</ul>");
resp.setStatus(HttpServletResponse.SC_OK);
resp.getWriter().println(getHeader());
resp.getWriter().println(html);
@ -55,8 +57,8 @@ public class MarkdownServlet extends AbstractDocServlet {
}
private String markdownToHtml(String markdown) {
MutableDataSet options = new MutableDataSet();
Parser parser = Parser.builder(options).build();
var options = new MutableDataSet();
var parser = Parser.builder(options).build();
HtmlRenderer renderer = HtmlRenderer.builder(options).build();
Node document = parser.parse(markdown);
String html = renderer.render(document);

View File

@ -1,5 +1,7 @@
package ctbrec.docs;
import static javax.servlet.http.HttpServletResponse.*;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;
@ -9,41 +11,55 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.json.JSONArray;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SearchServlet extends AbstractDocServlet {
private static final Logger LOG = LoggerFactory.getLogger(SearchServlet.class);
private static final String Q = "term";
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
if(req.getParameter(Q) == null) {
error(resp, HttpServletResponse.SC_BAD_REQUEST, "Parameter \""+Q+"\" is missing");
return;
try {
if (req.getParameter(Q) == null) {
error(resp, HttpServletResponse.SC_BAD_REQUEST, "Parameter \"" + Q + "\" is missing");
return;
}
resp.setStatus(HttpServletResponse.SC_OK);
resp.setContentType("application/json");
var result = new JSONArray();
var pages = getPages();
String q = req.getParameter(Q).toLowerCase();
String[] tokens = q.split("\\s+");
searchPages(result, pages, tokens);
resp.getWriter().println(result.toString());
} catch (Exception e) {
try {
resp.sendError(SC_INTERNAL_SERVER_ERROR, "Internal Server Error");
} catch (IOException ioe) {
LOG.error("Error while sending error response", ioe);
}
}
}
resp.setStatus(HttpServletResponse.SC_OK);
resp.setContentType("application/json");
JSONArray result = new JSONArray();
List<String> pages = getPages();
String q = req.getParameter(Q).toLowerCase();
String[] tokens = q.split("\\s+");
private void searchPages(JSONArray result, List<String> pages, String[] tokens) throws IOException {
for (String page : pages) {
try {
String content = loadMarkdown("/docs/" + page).toLowerCase();
boolean allFound = true;
var allFound = true;
for (String token : tokens) {
if(!content.contains(token)) {
if (!content.contains(token)) {
allFound = false;
}
}
if(allFound) {
if (allFound) {
result.put(page);
}
} catch(FileNotFoundException e) {
} catch (FileNotFoundException e) {
// virtual page like index.md -> ignore
}
}
resp.getWriter().println(result.toString());
}
}

View File

@ -34,7 +34,7 @@ public class AutosizeAlert extends Alert {
setResizable(true);
getDialogPane().setMinHeight(Region.USE_PREF_SIZE);
if(parent != null) {
Stage stage = (Stage) getDialogPane().getScene().getWindow();
var stage = (Stage) getDialogPane().getScene().getWindow();
stage.getScene().getStylesheets().addAll(parent.getStylesheets());
InputStream icon = Dialogs.class.getResourceAsStream("/icon.png");
stage.getIcons().add(new Image(icon));

View File

@ -86,7 +86,6 @@ import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
import okhttp3.Request;
import okhttp3.Response;
public class CamrecApplication extends Application {
@ -104,7 +103,6 @@ public class CamrecApplication extends Application {
public static HttpClient httpClient;
public static String title;
private Stage primaryStage;
private RecordedTab modelsTab;
private RecordingsTab recordingsTab;
private ScheduledExecutorService scheduler;
private int activeRecordings = 0;
@ -114,7 +112,7 @@ public class CamrecApplication extends Application {
public void start(Stage primaryStage) throws Exception {
this.primaryStage = primaryStage;
scheduler = Executors.newScheduledThreadPool(1, r -> {
Thread t = new Thread(r);
var t = new Thread(r);
t.setDaemon(true);
t.setName("Scheduler");
return t;
@ -172,7 +170,7 @@ public class CamrecApplication extends Application {
private void registerClipboardListener() {
if (config.getSettings().monitorClipboard) {
ClipboardListener clipboardListener = new ClipboardListener(recorder, sites);
var clipboardListener = new ClipboardListener(recorder, sites);
scheduler.scheduleAtFixedRate(clipboardListener, 0, 1, TimeUnit.SECONDS);
}
}
@ -209,19 +207,19 @@ public class CamrecApplication extends Application {
int windowWidth = Config.getInstance().getSettings().windowWidth;
int windowHeight = Config.getInstance().getSettings().windowHeight;
Scene scene = new Scene(rootPane, windowWidth, windowHeight);
var scene = new Scene(rootPane, windowWidth, windowHeight);
primaryStage.setScene(scene);
Dialogs.setScene(scene);
rootPane.setCenter(tabPane);
rootPane.setBottom(statusBar);
for (Site site : sites) {
if (site.isEnabled()) {
SiteTab siteTab = new SiteTab(site, scene);
var siteTab = new SiteTab(site, scene);
tabPane.getTabs().add(siteTab);
}
}
modelsTab = new RecordedTab(recorder, sites);
var modelsTab = new RecordedTab(recorder, sites);
tabPane.getTabs().add(modelsTab);
recordingsTab = new RecordingsTab("Recordings", recorder, config);
tabPane.getTabs().add(recordingsTab);
@ -236,7 +234,7 @@ public class CamrecApplication extends Application {
switchToStartTab();
writeColorSchemeStyleSheet();
Color base = Color.web(Config.getInstance().getSettings().colorBase);
var base = Color.web(Config.getInstance().getSettings().colorBase);
if (!base.equals(Color.WHITE)) {
loadStyleSheet(primaryStage, "color.css");
}
@ -308,7 +306,7 @@ public class CamrecApplication extends Application {
}
// check for active recordings
boolean shutdownNow = false;
var shutdownNow = false;
if (config.getSettings().localRecording) {
try {
if (!recorder.getCurrentlyRecording().isEmpty()) {
@ -374,7 +372,7 @@ public class CamrecApplication extends Application {
private void registerAlertSystem() {
for (EventHandlerConfiguration eventHandlerConfig : Config.getInstance().getSettings().eventHandlers) {
EventHandler handler = new EventHandler(eventHandlerConfig);
var handler = new EventHandler(eventHandlerConfig);
EventBusHolder.register(handler);
LOG.debug("Registered event handler for {} {}", eventHandlerConfig.getEvent(), eventHandlerConfig.getName());
}
@ -428,13 +426,13 @@ public class CamrecApplication extends Application {
bytesPerSecond = 0;
}
String humanReadable = ByteUnitFormatter.format(bytesPerSecond);
String status = String.format("Recording %s / %s models @ %s/s", activeRecordings, recorder.getModelCount(), humanReadable);
var status = String.format("Recording %s / %s models @ %s/s", activeRecordings, recorder.getModelCount(), humanReadable);
Platform.runLater(() -> statusLabel.setText(status));
}
private void writeColorSchemeStyleSheet() {
File colorCss = new File(Config.getInstance().getConfigDir(), "color.css");
try (FileOutputStream fos = new FileOutputStream(colorCss)) {
var colorCss = new File(Config.getInstance().getConfigDir(), "color.css");
try (var fos = new FileOutputStream(colorCss)) {
String content = ".root {\n" + " -fx-base: " + Config.getInstance().getSettings().colorBase + ";\n" + " -fx-accent: "
+ Config.getInstance().getSettings().colorAccent + ";\n" + " -fx-default-button: -fx-accent;\n" + " -fx-focus-color: -fx-accent;\n"
+ " -fx-control-inner-background-alt: derive(-fx-base, 95%);\n" + "}";
@ -445,7 +443,7 @@ public class CamrecApplication extends Application {
}
public static void loadStyleSheet(Stage primaryStage, String filename) {
File css = new File(Config.getInstance().getConfigDir(), filename);
var css = new File(Config.getInstance().getConfigDir(), filename);
if (css.exists() && css.isFile()) {
primaryStage.getScene().getStylesheets().add(css.toURI().toString());
}
@ -509,20 +507,20 @@ public class CamrecApplication extends Application {
}
private void checkForUpdates() {
Thread updateCheck = new Thread(() -> {
String url = "https://pastebin.com/raw/mUxtKzyB";
Request request = new Request.Builder().url(url).build();
try (Response response = httpClient.execute(request)) {
String body = response.body().string();
var updateCheck = new Thread(() -> {
var url = "https://pastebin.com/raw/mUxtKzyB";
var request = new Request.Builder().url(url).build();
try (var response = httpClient.execute(request)) {
var body = response.body().string();
LOG.trace("Version check respone: {}", body);
if (response.isSuccessful()) {
Moshi moshi = new Moshi.Builder().build();
var 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(body);
Release latest = releases.get(0);
Version latestVersion = latest.getVersion();
Version ctbrecVersion = getVersion();
var latest = releases.get(0);
var latestVersion = latest.getVersion();
var ctbrecVersion = getVersion();
if (latestVersion.compareTo(ctbrecVersion) > 0) {
LOG.debug("Update available {} < {}", ctbrecVersion, latestVersion);
Platform.runLater(() -> tabPane.getTabs().add(new UpdateTab(latest)));
@ -546,8 +544,8 @@ public class CamrecApplication extends Application {
return Version.of("0.0.0-DEV");
} else {
try (InputStream is = CamrecApplication.class.getClassLoader().getResourceAsStream("version")) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String versionString = reader.readLine();
var reader = new BufferedReader(new InputStreamReader(is));
var versionString = reader.readLine();
return Version.of(versionString);
}
}

View File

@ -1,19 +1,19 @@
package ctbrec.ui;
import ctbrec.Model;
import ctbrec.recorder.Recorder;
import ctbrec.sites.Site;
import javafx.application.Platform;
import javafx.scene.input.Clipboard;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.Objects;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ctbrec.recorder.Recorder;
import ctbrec.sites.Site;
import javafx.application.Platform;
import javafx.scene.input.Clipboard;
public class ClipboardListener implements Runnable {
private static final Logger LOG = LoggerFactory.getLogger(ClipboardListener.class);
@ -50,7 +50,7 @@ public class ClipboardListener implements Runnable {
private void addModelIfUrlMatches(String url) {
for (Site site : sites) {
Model m = site.createModelFromUrl(url);
var m = site.createModelFromUrl(url);
if (m != null) {
try {
recorder.addModel(m);

View File

@ -2,7 +2,6 @@ package ctbrec.ui;
import java.awt.AWTException;
import java.awt.Desktop;
import java.awt.Image;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
@ -65,8 +64,8 @@ public class DesktopIntegration {
}
// try external helpers
String[] externalHelpers = { "kde-open5", "kde-open", "gnome-open", "xdg-open" };
Runtime rt = Runtime.getRuntime();
var externalHelpers = new String[] { "kde-open5", "kde-open", "gnome-open", "xdg-open" };
var rt = Runtime.getRuntime();
for (String helper : externalHelpers) {
try {
rt.exec(helper + " " + uri);
@ -80,9 +79,9 @@ public class DesktopIntegration {
Alert info = new AutosizeAlert(Alert.AlertType.ERROR);
info.setTitle("Open URL");
info.setContentText("Couldn't open URL");
BorderPane pane = new BorderPane();
var pane = new BorderPane();
pane.setTop(new Label());
TextField urlField = new TextField(uri);
var urlField = new TextField(uri);
urlField.setPadding(new Insets(10));
urlField.setEditable(false);
pane.setCenter(urlField);
@ -100,8 +99,8 @@ public class DesktopIntegration {
}
// try external helpers
String[] externalHelpers = { "kde-open5", "kde-open", "gnome-open", "xdg-open" };
Runtime rt = Runtime.getRuntime();
var externalHelpers = new String[] { "kde-open5", "kde-open", "gnome-open", "xdg-open" };
var rt = Runtime.getRuntime();
for (String helper : externalHelpers) {
try {
rt.exec(helper + " " + f.getAbsolutePath());
@ -115,9 +114,9 @@ public class DesktopIntegration {
Alert info = new AutosizeAlert(Alert.AlertType.ERROR);
info.setTitle("Open file");
info.setContentText("Couldn't open file");
BorderPane pane = new BorderPane();
var pane = new BorderPane();
pane.setTop(new Label());
TextField urlField = new TextField(f.toString());
var urlField = new TextField(f.toString());
urlField.setPadding(new Insets(10));
urlField.setEditable(false);
pane.setCenter(urlField);
@ -189,7 +188,7 @@ public class DesktopIntegration {
if (tray == null) {
String title = CamrecApplication.title;
tray = SystemTray.getSystemTray();
Image image = Toolkit.getDefaultToolkit().createImage(DesktopIntegration.class.getResource("/icon64.png"));
var image = Toolkit.getDefaultToolkit().createImage(DesktopIntegration.class.getResource("/icon64.png"));
PopupMenu menu = createTrayContextMenu(stage);
trayIcon = new TrayIcon(image, title, menu);
@ -217,12 +216,12 @@ public class DesktopIntegration {
}
private static PopupMenu createTrayContextMenu(Stage stage) {
PopupMenu menu = new PopupMenu();
MenuItem show = new MenuItem("Show");
var menu = new PopupMenu();
var show = new MenuItem("Show");
show.addActionListener(evt -> restoreStage(stage));
menu.add(show);
menu.addSeparator();
MenuItem pauseRecording = new MenuItem("Pause recording");
var pauseRecording = new MenuItem("Pause recording");
pauseRecording.addActionListener(evt -> {
try {
recorder.pause();
@ -231,7 +230,7 @@ public class DesktopIntegration {
}
});
menu.add(pauseRecording);
MenuItem resumeRecording = new MenuItem("Resume recording");
var resumeRecording = new MenuItem("Resume recording");
resumeRecording.addActionListener(evt -> {
try {
recorder.resume();
@ -241,8 +240,8 @@ public class DesktopIntegration {
});
menu.add(resumeRecording);
menu.addSeparator();
MenuItem exit = new MenuItem("Exit");
exit.addActionListener(evt -> exit(stage));
var exit = new MenuItem("Exit");
exit.addActionListener(evt -> exit());
menu.add(exit);
return menu;
}
@ -266,7 +265,7 @@ public class DesktopIntegration {
});
}
private static void exit(Stage stage) {
private static void exit() {
EventBusHolder.BUS.post(Map.of("event", "shutdown"));
}

View File

@ -20,7 +20,6 @@ import org.slf4j.LoggerFactory;
import ctbrec.Config;
import ctbrec.OS;
import ctbrec.Settings.ProxyType;
import ctbrec.io.StreamRedirector;
public class ExternalBrowser implements AutoCloseable {
@ -50,7 +49,7 @@ public class ExternalBrowser implements AutoCloseable {
addProxyConfig(jsonConfig.getJSONObject("config"));
File configDir = new File(Config.getInstance().getConfigDir(), "ctbrec-minimal-browser");
var configDir = new File(Config.getInstance().getConfigDir(), "ctbrec-minimal-browser");
String[] cmdline = OS.getBrowserCommand(configDir.getCanonicalPath());
Process p = new ProcessBuilder(cmdline).start();
if (LOG.isTraceEnabled()) {
@ -91,7 +90,7 @@ public class ExternalBrowser implements AutoCloseable {
}
private void connectToRemoteControlSocket() throws IOException {
for (int i = 0; i < 20; i++) {
for (var i = 0; i < 20; i++) {
try {
socket = new Socket("localhost", 3202);
in = socket.getInputStream();
@ -117,7 +116,7 @@ public class ExternalBrowser implements AutoCloseable {
}
public void executeJavaScript(String javaScript) throws IOException {
JSONObject script = new JSONObject();
var script = new JSONObject();
script.put("execute", javaScript);
out.write(script.toString().getBytes(UTF_8));
out.write('\n');
@ -138,7 +137,7 @@ public class ExternalBrowser implements AutoCloseable {
private void readBrowserOutput() {
LOG.debug("Browser output reader started");
try (BufferedReader br = new BufferedReader(new InputStreamReader(in))) {
try (var br = new BufferedReader(new InputStreamReader(in))) {
String line;
synchronized (browserReadyLock) {
browserReady = true;
@ -164,10 +163,10 @@ public class ExternalBrowser implements AutoCloseable {
}
private void addProxyConfig(JSONObject jsonConfig) {
ProxyType proxyType = Config.getInstance().getSettings().proxyType;
var proxyType = Config.getInstance().getSettings().proxyType;
switch (proxyType) {
case HTTP:
JSONObject proxy = new JSONObject();
var proxy = new JSONObject();
proxy.put("address",
"http=" + Config.getInstance().getSettings().proxyHost + ':' + Config.getInstance().getSettings().proxyPort
+ ";https=" + Config.getInstance().getSettings().proxyHost + ':' + Config.getInstance().getSettings().proxyPort);

View File

@ -12,7 +12,6 @@ import org.slf4j.LoggerFactory;
import ctbrec.io.HttpClient;
import ctbrec.recorder.ProgressListener;
import okhttp3.Request;
import okhttp3.Response;
public class FileDownload {
@ -28,13 +27,13 @@ public class FileDownload {
public void start(URL url, File target) throws IOException {
LOG.trace("Downloading file {} to {}", url, target);
Request request = new Request.Builder().url(url).addHeader("connection", "keep-alive").build();
Response response = httpClient.execute(request);
long fileSize = Long.parseLong(response.header("Content-Length", String.valueOf(Long.MAX_VALUE)));
var request = new Request.Builder().url(url).addHeader("connection", "keep-alive").build();
var response = httpClient.execute(request);
var fileSize = Long.parseLong(response.header("Content-Length", String.valueOf(Long.MAX_VALUE)));
InputStream in = null;
try (FileOutputStream fos = new FileOutputStream(target)) {
try (var fos = new FileOutputStream(target)) {
in = response.body().byteStream();
byte[] b = new byte[1024 * 100];
var b = new byte[1024 * 100];
long totalBytesRead = 0;
int length = -1;
while ((length = in.read(b)) >= 0) {

View File

@ -23,54 +23,63 @@ public class CheckModelAccountAction {
private Recorder recorder;
private String buttonText;
public CheckModelAccountAction(Button b, Recorder recorder) {
this.b = b;
this.recorder = recorder;
buttonText = b.getText();
}
public void execute(Predicate<Model> filter) {
String buttonText = b.getText();
b.setDisable(true);
Runnable checker = (() -> {
List<Model> deletedAccounts = new ArrayList<>();
try {
List<Model> models = recorder.getModels().stream() //
.filter(filter) //
.collect(Collectors.toList());
int total = models.size();
for (int i = 0; i < total; i++) {
final int counter = i+1;
Platform.runLater(() -> b.setText(buttonText + ' ' + counter + '/' + total));
Model modelToCheck = models.get(i);
try {
if (!modelToCheck.exists()) {
deletedAccounts.add(modelToCheck);
}
} catch (IOException e) {
LOG.warn("Couldn't check, if model account still exists", e);
}
}
checkModelAccounts(filter, deletedAccounts);
} finally {
Platform.runLater(() -> {
b.setDisable(false);
b.setText(buttonText);
if (!deletedAccounts.isEmpty()) {
StringBuilder sb = new StringBuilder();
for (Model deletedModel : deletedAccounts) {
String name = deletedModel.getDisplayName() + " ".repeat(30);
name = name.substring(0, 30);
sb.append(name).append(' ').append('(').append(deletedModel.getUrl()).append(')').append('\n');
}
boolean remove = Dialogs.showConfirmDialog("Deleted Accounts", sb.toString(),
"The following accounts seem to have been deleted. Do you want to remove them?", b.getScene());
if (remove) {
new StopRecordingAction(b, deletedAccounts, recorder).execute();
}
}
});
showResult(deletedAccounts);
}
});
GlobalThreadPool.submit(checker);
}
private void showResult(List<Model> deletedAccounts) {
Platform.runLater(() -> {
b.setDisable(false);
b.setText(buttonText);
if (!deletedAccounts.isEmpty()) {
var sb = new StringBuilder();
for (Model deletedModel : deletedAccounts) {
String name = deletedModel.getDisplayName() + " ".repeat(30);
name = name.substring(0, 30);
sb.append(name).append(' ').append('(').append(deletedModel.getUrl()).append(')').append('\n');
}
boolean remove = Dialogs.showConfirmDialog("Deleted Accounts", sb.toString(),
"The following accounts seem to have been deleted. Do you want to remove them?", b.getScene());
if (remove) {
new StopRecordingAction(b, deletedAccounts, recorder).execute();
}
}
});
}
private void checkModelAccounts(Predicate<Model> filter, List<Model> deletedAccounts) {
List<Model> models = recorder.getModels().stream() //
.filter(filter) //
.collect(Collectors.toList());
int total = models.size();
for (var i = 0; i < total; i++) {
final int counter = i+1;
Platform.runLater(() -> b.setText(buttonText + ' ' + counter + '/' + total));
var modelToCheck = models.get(i);
try {
if (!modelToCheck.exists()) {
deletedAccounts.add(modelToCheck);
}
} catch (IOException e) {
LOG.warn("Couldn't check, if model account still exists", e);
}
}
}
}

View File

@ -5,7 +5,6 @@ import java.util.function.Consumer;
import ctbrec.Config;
import ctbrec.Model;
import ctbrec.Settings;
import ctbrec.recorder.Recorder;
import ctbrec.ui.JavaFxModel;
import ctbrec.ui.controls.Dialogs;
@ -29,8 +28,8 @@ public class IgnoreModelsAction {
}
public void execute(Consumer<Model> callback) {
Settings settings = Config.getInstance().getSettings();
boolean confirmed = true;
var settings = Config.getInstance().getSettings();
var confirmed = true;
if (settings.confirmationForDangerousActions) {
int n = selectedModels.size();
String plural = n > 1 ? "s" : "";
@ -39,7 +38,7 @@ public class IgnoreModelsAction {
}
if (confirmed) {
for (Model model : selectedModels) {
Model modelToIgnore = unwrap(model);
var modelToIgnore = unwrap(model);
settings.ignoredModels.add(modelToIgnore.getUrl());
}
if (withRemoveDialog) {

View File

@ -24,7 +24,7 @@ public class OpenRecordingsDir {
public void execute() {
source.setCursor(Cursor.WAIT);
File fileForRecording = Config.getInstance().getFileForRecording(selectedModel, ".mp4", Instant.now());
var fileForRecording = Config.getInstance().getFileForRecording(selectedModel, ".mp4", Instant.now());
final File dir = getModelDirectory(fileForRecording);
if (dir.exists()) {
GlobalThreadPool.submit(() -> DesktopIntegration.open(dir));
@ -35,7 +35,7 @@ public class OpenRecordingsDir {
}
private File getModelDirectory(File fileForRecording) {
File dir = fileForRecording.getParentFile();
var dir = fileForRecording.getParentFile();
if (Config.getInstance().getSettings().recordingsDirStructure == DirectoryStructure.ONE_PER_RECORDING) {
dir = dir.getParentFile();
}

View File

@ -2,7 +2,6 @@ package ctbrec.ui.action;
import ctbrec.Config;
import ctbrec.Model;
import ctbrec.ui.SiteUI;
import ctbrec.ui.SiteUiFactory;
import ctbrec.ui.controls.Toast;
import javafx.application.Platform;
@ -21,8 +20,8 @@ public class PlayAction {
public void execute() {
source.setCursor(Cursor.WAIT);
Thread t = new Thread(() -> {
SiteUI siteUI = SiteUiFactory.getUi(selectedModel.getSite());
var t = new Thread(() -> {
var siteUI = SiteUiFactory.getUi(selectedModel.getSite());
boolean started = siteUI.play(selectedModel);
Platform.runLater(() -> {
if (started && Config.getInstance().getSettings().showPlayerStarting) {

View File

@ -27,7 +27,7 @@ public class RemoveTimeLimitAction {
public CompletableFuture<Boolean> execute() {
source.setCursor(Cursor.WAIT);
Instant unlimited = Instant.ofEpochMilli(Model.RECORD_INDEFINITELY);
var unlimited = Instant.ofEpochMilli(Model.RECORD_INDEFINITELY);
return CompletableFuture.supplyAsync(() -> {
try {
selectedModel.setRecordUntil(unlimited);

View File

@ -1,18 +1,18 @@
package ctbrec.ui.action;
import java.util.List;
import ctbrec.Model;
import ctbrec.recorder.Recorder;
import ctbrec.ui.controls.Dialogs;
import javafx.application.Platform;
import javafx.scene.Node;
import java.util.List;
public class StartRecordingAction extends ModelMassEditAction {
public StartRecordingAction(Node source, List<? extends Model> models, Recorder recorder) {
super(source, models);
action = (m) -> {
action = m -> {
try {
recorder.addModel(m);
} catch (Exception e) {

View File

@ -11,8 +11,6 @@ import ctbrec.ui.AutosizeAlert;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.geometry.Point2D;
import javafx.scene.Node;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
@ -36,7 +34,7 @@ public abstract class AbstractFileSelectionBox extends HBox {
protected boolean allowEmptyValue = false;
private Tooltip validationError = new Tooltip();
public AbstractFileSelectionBox() {
protected AbstractFileSelectionBox() {
super(5);
fileInput = new TextField();
fileInput.textProperty().addListener(textListener());
@ -45,7 +43,7 @@ public abstract class AbstractFileSelectionBox extends HBox {
validationError.hide();
}
});
Node browse = createBrowseButton();
var browse = createBrowseButton();
browse.disableProperty().bind(disableProperty());
fileInput.disableProperty().bind(disableProperty());
fileInput.textProperty().bindBidirectional(fileProperty);
@ -63,14 +61,14 @@ public abstract class AbstractFileSelectionBox extends HBox {
});
}
public AbstractFileSelectionBox(String initialValue) {
protected AbstractFileSelectionBox(String initialValue) {
this();
fileInput.setText(initialValue);
}
private ChangeListener<? super String> textListener() {
return (obs, o, n) -> {
String input = fileInput.getText();
var input = fileInput.getText();
if (StringUtil.isBlank(input)) {
if (allowEmptyValue) {
fileProperty.set("");
@ -78,19 +76,19 @@ public abstract class AbstractFileSelectionBox extends HBox {
return;
}
} else {
File program = new File(input);
var program = new File(input);
setFile(program);
}
};
}
protected void setFile(File file) {
String msg = validate(file);
var msg = validate(file);
if (msg != null) {
fileInput.setBorder(new Border(new BorderStroke(Color.RED, BorderStrokeStyle.DASHED, new CornerRadii(2), new BorderWidths(2))));
validationError.setText(msg);
fileInput.setTooltip(validationError);
Point2D p = fileInput.localToScreen(fileInput.getTranslateY(), fileInput.getTranslateY());
var p = fileInput.localToScreen(fileInput.getTranslateY(), fileInput.getTranslateY());
if (!validationError.isShowing() && getScene() != null) {
validationError.show(getScene().getWindow(), p.getX(), p.getY() + fileInput.getHeight() + 4);
}
@ -123,7 +121,7 @@ public abstract class AbstractFileSelectionBox extends HBox {
}
private Button createBrowseButton() {
Button button = new Button("Select");
var button = new Button("Select");
button.setOnAction(e -> choose());
button.prefHeightProperty().bind(this.heightProperty());
button.prefWidthProperty().set(70);
@ -131,14 +129,14 @@ public abstract class AbstractFileSelectionBox extends HBox {
}
protected void choose() {
FileChooser chooser = new FileChooser();
File program = chooser.showOpenDialog(null);
var chooser = new FileChooser();
var program = chooser.showOpenDialog(null);
if (program != null) {
try {
fileInput.setText(program.getCanonicalPath());
} catch (IOException e1) {
LOG.error("Couldn't determine path", e1);
Alert alert = new AutosizeAlert(Alert.AlertType.ERROR, getScene());
var alert = new AutosizeAlert(Alert.AlertType.ERROR, getScene());
alert.setTitle("Whoopsie");
alert.setContentText("Couldn't determine path");
alert.showAndWait();

View File

@ -19,8 +19,8 @@ public class DateTimeCellFactory<T> implements Callback<TableColumn<T, Instant>,
if (empty || item == null) {
setText("");
} else {
LocalDateTime dateTime = LocalDateTime.ofInstant(item, ZoneId.systemDefault());
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT);
var dateTime = LocalDateTime.ofInstant(item, ZoneId.systemDefault());
var formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT);
String formattedDateTime = formatter.format(dateTime);
setText(item.equals(Instant.EPOCH) ? "" : formattedDateTime);
}

View File

@ -12,14 +12,14 @@ public class DirectorySelectionBox extends AbstractFileSelectionBox {
@Override
protected void choose() {
DirectoryChooser chooser = new DirectoryChooser();
String preselection = Optional.ofNullable(fileProperty().get()).orElse(".");
File currentDir = new File(preselection);
var chooser = new DirectoryChooser();
var preselection = Optional.ofNullable(fileProperty().get()).orElse(".");
var currentDir = new File(preselection);
if (currentDir.exists() && currentDir.isDirectory()) {
chooser.setInitialDirectory(currentDir);
}
File selectedDir = chooser.showDialog(null);
if(selectedDir != null) {
if (selectedDir != null) {
fileInput.setText(selectedDir.getAbsolutePath());
setFile(selectedDir);
}
@ -27,12 +27,12 @@ public class DirectorySelectionBox extends AbstractFileSelectionBox {
@Override
protected String validate(File file) {
if(isDisabled()) {
if (isDisabled()) {
return null;
}
String msg = super.validate(file);
if(msg != null) {
if (msg != null) {
return msg;
} else if (!file.isDirectory()) {
return "This is not a directory";

View File

@ -10,9 +10,9 @@ public class FasterVerticalScrollPaneSkin extends ScrollPaneSkin {
super(scrollPane);
getSkinnable().addEventFilter(ScrollEvent.SCROLL, event -> {
double ratio = scrollPane.getViewportBounds().getHeight() / scrollPane.getContent().getBoundsInLocal().getHeight();
double baseUnitIncrement = 0.15;
double unitIncrement = baseUnitIncrement * ratio * 1.25;
var ratio = scrollPane.getViewportBounds().getHeight() / scrollPane.getContent().getBoundsInLocal().getHeight();
var baseUnitIncrement = 0.15;
var unitIncrement = baseUnitIncrement * ratio * 1.25;
getVerticalScrollBar().setUnitIncrement(unitIncrement);
if (event.getDeltaX() < 0) {

View File

@ -12,12 +12,12 @@ public class FileSelectionBox extends AbstractFileSelectionBox {
@Override
protected String validate(File file) {
if(isDisabled()) {
if (isDisabled()) {
return null;
}
String msg = super.validate(file);
if(msg != null) {
if (msg != null) {
return msg;
} else if (!file.isFile()) {
return "This is not a regular file";

View File

@ -46,10 +46,8 @@ import javafx.beans.property.SimpleDoubleProperty;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Point2D;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
@ -82,7 +80,7 @@ public class Popover extends Region implements EventHandler<Event>{
private final Region frameBorder = new Region();
private final Button leftButton = new Button("Left");
private final Button rightButton = new Button("Right");
private final LinkedList<Page> pages = new LinkedList<Page>();
private final LinkedList<Page> pages = new LinkedList<>();
private final Pane pagesPane = new Pane();
private final Rectangle pagesClipRect = new Rectangle();
private final Pane titlesPane = new Pane();
@ -128,11 +126,6 @@ public class Popover extends Region implements EventHandler<Event>{
t.consume();
}
};
// popoverScrollHandler = new EventHandler<ScrollEvent>() {
// @Override public void handle(ScrollEvent t) {
// t.consume(); // consume all scroll events
// }
// };
}
/**
@ -149,9 +142,9 @@ public class Popover extends Region implements EventHandler<Event>{
@Override protected double computeMinWidth(double height) {
Page page = pages.isEmpty() ? null : pages.getFirst();
if (page != null) {
Node n = page.getPageNode();
var n = page.getPageNode();
if (n != null) {
Insets insets = getInsets();
var insets = getInsets();
return insets.getLeft() + n.minWidth(-1) + insets.getRight();
}
}
@ -159,16 +152,16 @@ public class Popover extends Region implements EventHandler<Event>{
}
@Override protected double computeMinHeight(double width) {
Insets insets = getInsets();
var insets = getInsets();
return insets.getLeft() + 100 + insets.getRight();
}
@Override protected double computePrefWidth(double height) {
Page page = pages.isEmpty() ? null : pages.getFirst();
if (page != null) {
Node n = page.getPageNode();
var n = page.getPageNode();
if (n != null) {
Insets insets = getInsets();
var insets = getInsets();
return insets.getLeft() + n.prefWidth(-1) + insets.getRight();
}
}
@ -180,9 +173,9 @@ public class Popover extends Region implements EventHandler<Event>{
double maxHeight = maxHeight(-1);
double prefHeight = popoverHeight.get();
if (prefHeight == -1) {
Page page = pages.getFirst();
var page = pages.getFirst();
if (page != null) {
Insets inset = getInsets();
var inset = getInsets();
if (width == -1) {
width = prefWidth(-1);
}
@ -208,7 +201,7 @@ public class Popover extends Region implements EventHandler<Event>{
}
@Override protected double computeMaxHeight(double width) {
Scene scene = getScene();
var scene = getScene();
if (scene != null) {
return scene.getHeight() - 100;
} else {
@ -220,14 +213,14 @@ public class Popover extends Region implements EventHandler<Event>{
if (maxPopupHeight == -1) {
maxPopupHeight = (int)getScene().getHeight()-100;
}
final Insets insets = getInsets();
final var insets = getInsets();
final int width = (int)getWidth();
final int height = (int)getHeight();
final int top = (int)insets.getTop() + 40;
final int right = (int)insets.getRight();
final int bottom = (int)insets.getBottom();
final int left = (int)insets.getLeft();
final int offset = 18;
final var offset = 18;
int pageWidth = width - left - right;
int pageHeight = height - top - bottom;
@ -238,19 +231,18 @@ public class Popover extends Region implements EventHandler<Event>{
pagesClipRect.setWidth(pageWidth);
pagesClipRect.setHeight(pageHeight);
int pageX = 0;
var pageX = 0;
for (Node page : pagesPane.getChildren()) {
page.resizeRelocate(pageX, 0, pageWidth, pageHeight);
pageX += pageWidth + PAGE_GAP;
}
int buttonHeight = (int)(leftButton.prefHeight(-1));
if (buttonHeight < 30) buttonHeight = 30;
final int buttonTop = (int)((top-buttonHeight)/2d);
final int leftButtonWidth = (int)snapSizeX(leftButton.prefWidth(-1));
leftButton.resizeRelocate(left, buttonTop + offset,leftButtonWidth,buttonHeight);
final int rightButtonWidth = (int)snapSizeX(rightButton.prefWidth(-1));
rightButton.resizeRelocate(width-right-rightButtonWidth, buttonTop + offset,rightButtonWidth,buttonHeight);
int buttonHeight = Math.min(30, (int) (leftButton.prefHeight(-1)));
final int buttonTop = (int) ((top - buttonHeight) / 2d);
final int leftButtonWidth = (int) snapSizeX(leftButton.prefWidth(-1));
leftButton.resizeRelocate(left, (double)buttonTop + offset, leftButtonWidth, buttonHeight);
final int rightButtonWidth = (int) snapSizeX(rightButton.prefWidth(-1));
rightButton.resizeRelocate(width - (double)right - rightButtonWidth, (double)buttonTop + offset, rightButtonWidth, buttonHeight);
if (title != null) {
double tw = title.getWidth();
@ -275,16 +267,16 @@ public class Popover extends Region implements EventHandler<Event>{
}
public final void popPage() {
Page oldPage = pages.pop();
var oldPage = pages.pop();
oldPage.handleHidden();
oldPage.setPopover(null);
Page page = pages.getFirst();
var page = pages.getFirst();
leftButton.setVisible(page.leftButtonText() != null);
leftButton.setText(page.leftButtonText());
rightButton.setVisible(page.rightButtonText() != null);
rightButton.setText(page.rightButtonText());
if (pages.size() > 0) {
final Insets insets = getInsets();
if (!pages.isEmpty()) {
final var insets = getInsets();
final int width = (int)prefWidth(-1);
final int right = (int)insets.getRight();
final int left = (int)insets.getLeft();
@ -308,10 +300,10 @@ public class Popover extends Region implements EventHandler<Event>{
}
public final void pushPage(final Page page) {
final Node pageNode = page.getPageNode();
final var pageNode = page.getPageNode();
pageNode.setManaged(false);
pagesPane.getChildren().add(pageNode);
final Insets insets = getInsets();
final var insets = getInsets();
final int pageWidth = (int)(prefWidth(-1) - insets.getLeft() - insets.getRight());
final int newPageX = (pageWidth + PAGE_GAP) * pages.size();
leftButton.setVisible(page.leftButtonText() != null);
@ -322,11 +314,11 @@ public class Popover extends Region implements EventHandler<Event>{
title = new Label(page.getPageTitle());
title.getStyleClass().add("popover-title");
title.setTextAlignment(TextAlignment.CENTER);
title.setTranslateX(newPageX + (int) ((pageWidth - title.getLayoutBounds().getWidth()) / 2d));
title.setTranslateX(newPageX + (pageWidth - title.getLayoutBounds().getWidth()) / 2d);
titlesPane.getChildren().add(title);
if (!pages.isEmpty() && isVisible()) {
final Timeline timeline = new Timeline(
final var timeline = new Timeline(
new KeyFrame(Duration.millis(350), (ActionEvent t) -> {
pagesPane.setCache(false);
resizePopoverToNewPage(pageNode);
@ -344,7 +336,7 @@ public class Popover extends Region implements EventHandler<Event>{
}
private void resizePopoverToNewPage(final Node newPageNode) {
final Insets insets = getInsets();
final var insets = getInsets();
final double width = prefWidth(-1);
final double contentWidth = width - insets.getLeft() - insets.getRight();
double h = newPageNode.prefHeight(contentWidth);
@ -366,7 +358,6 @@ public class Popover extends Region implements EventHandler<Event>{
if (!isVisible() || fadeAnimation != null) {
this.onHideCallback = onHideCallback;
getScene().addEventFilter(MouseEvent.MOUSE_CLICKED, popoverHideHandler);
// getScene().addEventFilter(ScrollEvent.ANY,popoverScrollHandler);
if (fadeAnimation != null) {
fadeAnimation.stop();
@ -376,17 +367,15 @@ public class Popover extends Region implements EventHandler<Event>{
setVisible(true);
}
FadeTransition fade = new FadeTransition(Duration.seconds(.1), this);
var fade = new FadeTransition(Duration.seconds(.1), this);
fade.setToValue(1.0);
fade.setOnFinished((ActionEvent event) -> {
fadeAnimation = null;
});
fade.setOnFinished((ActionEvent event) -> fadeAnimation = null);
ScaleTransition scale = new ScaleTransition(Duration.seconds(.1), this);
var scale = new ScaleTransition(Duration.seconds(.1), this);
scale.setToX(1);
scale.setToY(1);
ParallelTransition tx = new ParallelTransition(fade, scale);
var tx = new ParallelTransition(fade, scale);
fadeAnimation = tx;
tx.play();
}
@ -395,26 +384,24 @@ public class Popover extends Region implements EventHandler<Event>{
public void hide(){
if (isVisible() || fadeAnimation != null) {
getScene().removeEventFilter(MouseEvent.MOUSE_CLICKED, popoverHideHandler);
// getScene().removeEventFilter(ScrollEvent.ANY,popoverScrollHandler);
if (fadeAnimation != null) {
fadeAnimation.stop();
}
FadeTransition fade = new FadeTransition(Duration.seconds(.1), this);
var fade = new FadeTransition(Duration.seconds(.1), this);
fade.setToValue(0);
fade.setOnFinished((ActionEvent event) -> {
fadeAnimation = null;
setVisible(false);
//clearPages();
if (onHideCallback != null) onHideCallback.run();
});
ScaleTransition scale = new ScaleTransition(Duration.seconds(.1), this);
var scale = new ScaleTransition(Duration.seconds(.1), this);
scale.setToX(.8);
scale.setToY(.8);
ParallelTransition tx = new ParallelTransition(fade, scale);
var tx = new ParallelTransition(fade, scale);
fadeAnimation = tx;
tx.play();
}

View File

@ -55,7 +55,7 @@ public class PopoverTreeList<T> extends ListView<T> implements Callback<ListView
return new TreeItemListCell();
}
protected void itemClicked(T item) {}
protected void itemClicked(T item) { /* nothing to do */ }
private class TreeItemListCell extends ListCell<T> implements EventHandler<MouseEvent> {
private TreeItemListCell() {

View File

@ -12,12 +12,12 @@ public class ProgramSelectionBox extends FileSelectionBox {
@Override
protected String validate(File file) {
if(isDisabled()) {
if (isDisabled()) {
return null;
}
String msg = super.validate(file);
if(msg != null) {
if (msg != null) {
return msg;
} else if (!file.canExecute()) {
return "This is not an executable application";

View File

@ -34,4 +34,3 @@ public class RecordingIndicator extends StackPane {
icon.setImage(img);
}
}

View File

@ -44,10 +44,10 @@ import javafx.scene.layout.Region;
* Search field with styling and a clear button
*/
public class SearchBox extends TextField implements ChangeListener<String>{
private static final int PREF_HEIGHT = 26;
private final Button clearButton = new Button();
private final Region innerBackground = new Region();
private final Region icon = new Region();
private final int prefHeight = 26;
public SearchBox() {
getStyleClass().addAll("search-box");
@ -55,7 +55,7 @@ public class SearchBox extends TextField implements ChangeListener<String>{
innerBackground.getStyleClass().setAll("search-box-inner");
setPromptText("Search");
textProperty().addListener(this);
setPrefHeight(prefHeight);
setPrefHeight(PREF_HEIGHT);
clearButton.getStyleClass().setAll("search-clear-button");
clearButton.setCursor(Cursor.DEFAULT);
clearButton.setOnMouseClicked((MouseEvent t) -> {
@ -91,10 +91,10 @@ public class SearchBox extends TextField implements ChangeListener<String>{
innerBackground.resize(getWidth(), getHeight());
icon.setLayoutX(0);
icon.setLayoutY(0);
icon.resize(35,prefHeight);
clearButton.setLayoutX(getWidth() - prefHeight);
icon.resize(35,PREF_HEIGHT);
clearButton.setLayoutX(getWidth() - PREF_HEIGHT);
clearButton.setLayoutY(0);
clearButton.resize(prefHeight, prefHeight);
clearButton.resize(PREF_HEIGHT, PREF_HEIGHT);
}
@Override public void changed(ObservableValue<? extends String> ov, String oldValue, String newValue) {

View File

@ -1,6 +1,5 @@
package ctbrec.ui.controls.autocomplete;
import java.util.Optional;
import javafx.event.ActionEvent;
@ -36,18 +35,18 @@ public class AutoFillTextField extends TextField {
private void autocomplete(boolean fulltextSearch) {
String oldtext = getOldText();
if(oldtext.isEmpty()) {
if (oldtext.isEmpty()) {
return;
}
Optional<String> match = null;
if(fulltextSearch) {
Optional<String> match;
if (fulltextSearch) {
match = suggester.fulltext(oldtext);
} else {
match = suggester.startsWith(oldtext);
}
if(match.isPresent()) {
if (match.isPresent()) {
setText(match.get());
int pos = oldtext.length();
positionCaret(pos);
@ -56,7 +55,7 @@ public class AutoFillTextField extends TextField {
}
private String getOldText() {
if(getSelection().getLength() > 0) {
if (getSelection().getLength() > 0) {
return getText().substring(0, getSelection().getStart());
} else {
return getText();

View File

@ -1,5 +0,0 @@
package ctbrec.ui.controls.autocomplete;
public class Suggestion {
}

View File

@ -35,8 +35,8 @@ public class RangeSliderBehavior<T extends Number> extends BehaviorBase<RangeSli
* The mouse position on track with 0.0 being beginning of track and 1.0 being the end
*/
public void lowThumbDragged(double position) {
T newPosition = getNewPosition(position);
T high = getHigh();
var newPosition = getNewPosition(position);
var high = getHigh();
if (newPosition.doubleValue() >= high.doubleValue()) {
newPosition = getLow();
}
@ -48,8 +48,8 @@ public class RangeSliderBehavior<T extends Number> extends BehaviorBase<RangeSli
* The mouse position on track with 0.0 being beginning of track and 1.0 being the end
*/
public void highThumbDragged(double position) {
T newPosition = getNewPosition(position);
T low = getLow();
var newPosition = getNewPosition(position);
var low = getLow();
if (newPosition.doubleValue() <= low.doubleValue()) {
newPosition = getHigh();
}
@ -57,9 +57,9 @@ public class RangeSliderBehavior<T extends Number> extends BehaviorBase<RangeSli
}
public void moveClosestThumbTo(double positionPercentage) {
T newPosition = getNewPosition(positionPercentage);
T low = getLow();
T high = getHigh();
var newPosition = getNewPosition(positionPercentage);
var low = getLow();
var high = getHigh();
double distToLow = Math.abs(low.doubleValue() - newPosition.doubleValue());
double distToHigh = Math.abs(high.doubleValue() - newPosition.doubleValue());
if (distToLow < distToHigh) {

View File

@ -122,39 +122,39 @@ public class RangeSliderSkin extends SkinBase<RangeSlider<?>> {
thumbRange.high.resize(thumbWidth, thumbHeight);
}
// we are assuming the is common radius's for all corners on the track
double trackRadius = track.getBackground() == null ? 0
: !track.getBackground().getFills().isEmpty() ? track.getBackground().getFills().get(0).getRadii().getTopLeftHorizontalRadius() : 0;
double tickLineHeight = (showTickMarks) ? tickLine.prefHeight(-1) : 0;
double trackHeight = 5;// track.prefHeight(-1);
double trackAreaHeight = Math.max(trackHeight, thumbHeight);
double totalHeightNeeded = trackAreaHeight + ((showTickMarks) ? TRACK_TO_TICK_GAP + tickLineHeight : 0);
double startY = y + ((h - totalHeightNeeded) / 2); // center slider in available height vertically
double radius = track.getBackground().getFills().isEmpty() ? 0 : track.getBackground().getFills().get(0).getRadii().getTopLeftHorizontalRadius();
double trackRadius = track.getBackground() == null ? 0 : radius;
trackLength = w - thumbWidth;
trackStart = x + (thumbWidth / 2);
double tickLineHeight = (showTickMarks) ? tickLine.prefHeight(-1) : 0;
double trackHeight = 5;
double trackAreaHeight = Math.max(trackHeight, thumbHeight);
double totalHeightNeeded = trackAreaHeight + ((showTickMarks) ? TRACK_TO_TICK_GAP + tickLineHeight : 0);
double startY = y + ((h - totalHeightNeeded) / 2); // center slider in available height vertically
double trackTop = (int) (startY + ((trackAreaHeight - trackHeight) / 2));
lowThumbPos = (int) (startY + ((trackAreaHeight - thumbHeight) / 2));
trackLength = w - thumbWidth;
trackStart = x + (thumbWidth / 2);
// layout track
track.resizeRelocate(trackStart - trackRadius, trackTop, trackLength + trackRadius + trackRadius, trackHeight);
double trackTop = (int) (startY + ((trackAreaHeight - trackHeight) / 2));
lowThumbPos = (int) (startY + ((trackAreaHeight - thumbHeight) / 2));
positionThumbs();
// layout track
track.resizeRelocate(trackStart - trackRadius, trackTop, trackLength + trackRadius + trackRadius, trackHeight);
if (showTickMarks) {
tickLine.setLayoutX(trackStart);
tickLine.setLayoutY(trackTop + trackHeight + TRACK_TO_TICK_GAP);
tickLine.resize(trackLength, tickLineHeight);
tickLine.requestAxisLayout();
} else {
if (tickLine != null) {
tickLine.resize(0, 0);
tickLine.requestAxisLayout();
}
tickLine = null;
}
positionThumbs();
if (showTickMarks) {
tickLine.setLayoutX(trackStart);
tickLine.setLayoutY(trackTop + trackHeight + TRACK_TO_TICK_GAP);
tickLine.resize(trackLength, tickLineHeight);
tickLine.requestAxisLayout();
} else {
if (tickLine != null) {
tickLine.resize(0, 0);
tickLine.requestAxisLayout();
}
tickLine = null;
}
}
private void positionThumbs() {

View File

@ -23,13 +23,13 @@ public class PlaySound extends Action {
@Override
public void accept(Event evt) {
AudioClip clip = new AudioClip(url.toString());
var clip = new AudioClip(url.toString());
clip.play();
}
@Override
public void configure(ActionConfiguration config) throws Exception {
File file = new File((String) config.getConfiguration().get("file"));
var file = new File((String) config.getConfiguration().get("file"));
url = file.toURI().toURL();
}
}

View File

@ -17,7 +17,7 @@ public class ShowNotification extends Action {
@Override
public void accept(Event evt) {
String header = evt.getType().toString();
var header = evt.getType().toString();
String msg;
switch(evt.getType()) {
case MODEL_STATUS_CHANGED:
@ -25,7 +25,7 @@ public class ShowNotification extends Action {
if (modelEvent.getOldState() == Model.State.UNKNOWN) {
return;
}
Model m = modelEvent.getModel();
var m = modelEvent.getModel();
msg = m.getDisplayName() + " is now " + modelEvent.getNewState().toString();
break;
case RECORDING_STATUS_CHANGED:
@ -41,5 +41,6 @@ public class ShowNotification extends Action {
@Override
public void configure(ActionConfiguration config) throws Exception {
// nothing to do here
}
}

View File

@ -22,7 +22,6 @@ import javafx.scene.control.ScrollPane;
import javafx.scene.control.Tab;
import javafx.scene.layout.VBox;
import okhttp3.Request;
import okhttp3.Response;
public class NewsTab extends Tab implements TabSelectionListener {
private static final String ACCESS_TOKEN = "a2804d73a89951a22e0f8483a6fcec8943afd88b7ba17c459c095aa9e6f94fd0";
@ -44,14 +43,14 @@ public class NewsTab extends Tab implements TabSelectionListener {
private void loadToots() {
try {
Request request = new Request.Builder()
var request = new Request.Builder()
.url(URL)
.header("Authorization", "Bearer " + ACCESS_TOKEN)
.header(USER_AGENT, "ctbrec " + CamrecApplication.getVersion().toString())
.build();
try (Response response = CamrecApplication.httpClient.execute(request)) {
try (var response = CamrecApplication.httpClient.execute(request)) {
if (response.isSuccessful()) {
String body = response.body().string();
var body = response.body().string();
if (body.startsWith("[")) {
onSuccess(body);
} else if (body.startsWith("{")) {
@ -69,7 +68,7 @@ public class NewsTab extends Tab implements TabSelectionListener {
}
private void onError(String body) throws IOException {
JSONObject json = new JSONObject(body);
var json = new JSONObject(body);
if (json.has("error")) {
throw new IOException("Request not successful: " + json.getString("error"));
} else {
@ -78,14 +77,14 @@ public class NewsTab extends Tab implements TabSelectionListener {
}
private void onSuccess(String body) throws IOException {
Moshi moshi = new Moshi.Builder().build();
var moshi = new Moshi.Builder().build();
JsonAdapter<Status[]> statusListAdapter = moshi.adapter(Status[].class);
Status[] statusArray = statusListAdapter.fromJson(body);
Platform.runLater(() -> {
layout.getChildren().clear();
for (Status status : statusArray) {
if (status.getInReplyToId() == null && !Objects.equals("direct", status.getVisibility())) {
StatusPane stp = new StatusPane(status);
var stp = new StatusPane(status);
layout.getChildren().add(stp);
VBox.setMargin(stp, new Insets(10));
}

View File

@ -272,8 +272,8 @@ public class Status {
public ZonedDateTime getCreationTime() {
String timestamp = getCreatedAt();
Instant instant = Instant.parse(timestamp);
ZonedDateTime time = ZonedDateTime.ofInstant(instant, ZoneId.systemDefault());
var instant = Instant.parse(timestamp);
var time = ZonedDateTime.ofInstant(instant, ZoneId.systemDefault());
return time;
}
}

View File

@ -36,7 +36,7 @@ public class StatusPane extends StackPane {
ZonedDateTime createdAt = status.getCreationTime();
String creationTime = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT, FormatStyle.SHORT).format(createdAt);
Label time = new Label(creationTime);
var time = new Label(creationTime);
time.setStyle("-fx-background-color: -fx-base");
time.setOpacity(.7);
time.setPadding(new Insets(3));
@ -45,7 +45,7 @@ public class StatusPane extends StackPane {
getChildren().add(time);
StackPane.setMargin(time, new Insets(5, 5, 5, 10));
StackPane.setAlignment(time, Pos.BOTTOM_LEFT);
Rectangle clip = new Rectangle(time.getWidth(), time.getHeight());
var clip = new Rectangle(time.getWidth(), time.getHeight());
clip.heightProperty().bind(time.heightProperty());
clip.widthProperty().bind(time.widthProperty());
clip.setArcHeight(5);
@ -53,7 +53,7 @@ public class StatusPane extends StackPane {
time.setClip(clip);
reply = new Button("Reply");
reply.setOnAction((evt) -> DesktopIntegration.open(status.getUrl()));
reply.setOnAction(evt -> DesktopIntegration.open(status.getUrl()));
getChildren().add(reply);
StackPane.setMargin(reply, new Insets(5, 5, 5, 5));
StackPane.setAlignment(reply, Pos.BOTTOM_RIGHT);
@ -64,7 +64,7 @@ public class StatusPane extends StackPane {
ObservableList<Node> childrenUnmodifiable = content.getChildrenUnmodifiable();
for (Node node : childrenUnmodifiable) {
if (node instanceof ScrollPane) {
ScrollPane scrollPane = (ScrollPane) node;
var scrollPane = (ScrollPane) node;
Set<Node> nodes = scrollPane.lookupAll(".scroll-bar");
for (final Node child : nodes) {
if (child instanceof ScrollBar) {

View File

@ -47,13 +47,12 @@ public abstract class AbstractPostProcessingPaneFactory {
}
class MapPreferencesStorage implements PreferencesStorage {
@Override
public void save(Preferences preferences) throws IOException {
for (Property<?> property : properties) {
String key = property.getName();
Object value = preferences.getSetting(key).get().getProperty().getValue();
LOG.debug("{}={}", key, value.toString());
LOG.debug("{}={}", key, value);
pp.getConfig().put(key, value.toString());
}
}
@ -64,7 +63,7 @@ public abstract class AbstractPostProcessingPaneFactory {
}
@Override
public Node createGui(Setting setting) throws Exception {
public Node createGui(Setting setting) throws NoSuchFieldException, IllegalAccessException {
Property<?> prop = setting.getProperty();
if (prop instanceof ExclusiveSelectionProperty) {
return createRadioGroup(setting);
@ -86,109 +85,74 @@ public abstract class AbstractPostProcessingPaneFactory {
return new Label("Unsupported Type for key " + setting.getKey() + ": " + setting.getProperty());
}
}
}
private Node createRadioGroup(Setting setting) {
ExclusiveSelectionProperty prop = (ExclusiveSelectionProperty) setting.getProperty();
ToggleGroup toggleGroup = new ToggleGroup();
RadioButton optionA = new RadioButton(prop.getOptionA());
optionA.setSelected(prop.getValue());
optionA.setToggleGroup(toggleGroup);
RadioButton optionB = new RadioButton(prop.getOptionB());
optionB.setSelected(!optionA.isSelected());
optionB.setToggleGroup(toggleGroup);
optionA.selectedProperty().bindBidirectional(prop);
HBox row = new HBox();
row.getChildren().addAll(optionA, optionB);
HBox.setMargin(optionA, new Insets(5));
HBox.setMargin(optionB, new Insets(5));
return row;
}
private Node createRadioGroup(Setting setting) {
ExclusiveSelectionProperty prop = (ExclusiveSelectionProperty) setting.getProperty();
var toggleGroup = new ToggleGroup();
var optionA = new RadioButton(prop.getOptionA());
optionA.setSelected(prop.getValue());
optionA.setToggleGroup(toggleGroup);
var optionB = new RadioButton(prop.getOptionB());
optionB.setSelected(!optionA.isSelected());
optionB.setToggleGroup(toggleGroup);
optionA.selectedProperty().bindBidirectional(prop);
var row = new HBox();
row.getChildren().addAll(optionA, optionB);
HBox.setMargin(optionA, new Insets(5));
HBox.setMargin(optionB, new Insets(5));
return row;
}
private Node createFileSelector(Setting setting) {
ProgramSelectionBox programSelector = new ProgramSelectionBox("");
// programSelector.fileProperty().addListener((obs, o, n) -> saveValue(() -> {
// String path = n;
// Field field = Settings.class.getField(setting.getKey());
// String oldValue = (String) field.get(settings);
// if (!Objects.equals(path, oldValue)) {
// field.set(settings, path);
// config.save();
// }
// }));
StringProperty property = (StringProperty) setting.getProperty();
programSelector.fileProperty().bindBidirectional(property);
return programSelector;
}
private Node createFileSelector(Setting setting) {
var programSelector = new ProgramSelectionBox("");
StringProperty property = (StringProperty) setting.getProperty();
programSelector.fileProperty().bindBidirectional(property);
return programSelector;
}
private Node createDirectorySelector(Setting setting) {
DirectorySelectionBox directorySelector = new DirectorySelectionBox("");
directorySelector.prefWidth(400);
// directorySelector.fileProperty().addListener((obs, o, n) -> saveValue(() -> {
// String path = n;
// Field field = Settings.class.getField(setting.getKey());
// String oldValue = (String) field.get(settings);
// if (!Objects.equals(path, oldValue)) {
// field.set(settings, path);
// config.save();
// }
// }));
StringProperty property = (StringProperty) setting.getProperty();
directorySelector.fileProperty().bindBidirectional(property);
return directorySelector;
}
private Node createDirectorySelector(Setting setting) {
var directorySelector = new DirectorySelectionBox("");
directorySelector.prefWidth(400);
StringProperty property = (StringProperty) setting.getProperty();
directorySelector.fileProperty().bindBidirectional(property);
return directorySelector;
}
@SuppressWarnings("unchecked")
private Node createStringProperty(Setting setting) {
TextField ctrl = new TextField();
ctrl.textProperty().bindBidirectional(setting.getProperty());
return ctrl;
}
@SuppressWarnings("unchecked")
private Node createStringProperty(Setting setting) {
var ctrl = new TextField();
ctrl.textProperty().bindBidirectional(setting.getProperty());
return ctrl;
}
@SuppressWarnings("unchecked")
private Node createIntegerProperty(Setting setting) {
TextField ctrl = new TextField();
Property<Number> prop = setting.getProperty();
ctrl.textProperty().bindBidirectional(prop, new NumberStringConverter());
return ctrl;
}
@SuppressWarnings("unchecked")
private Node createIntegerProperty(Setting setting) {
var ctrl = new TextField();
Property<Number> prop = setting.getProperty();
ctrl.textProperty().bindBidirectional(prop, new NumberStringConverter());
return ctrl;
}
@SuppressWarnings("unchecked")
private Node createLongProperty(Setting setting) {
TextField ctrl = new TextField();
Property<Number> prop = setting.getProperty();
ctrl.textProperty().bindBidirectional(prop, new NumberStringConverter());
return ctrl;
}
@SuppressWarnings("unchecked")
private Node createLongProperty(Setting setting) {
var ctrl = new TextField();
Property<Number> prop = setting.getProperty();
ctrl.textProperty().bindBidirectional(prop, new NumberStringConverter());
return ctrl;
}
private Node createBooleanProperty(Setting setting) {
CheckBox ctrl = new CheckBox();
BooleanProperty prop = (BooleanProperty) setting.getProperty();
ctrl.selectedProperty().bindBidirectional(prop);
return ctrl;
}
private Node createBooleanProperty(Setting setting) {
var ctrl = new CheckBox();
BooleanProperty prop = (BooleanProperty) setting.getProperty();
ctrl.selectedProperty().bindBidirectional(prop);
return ctrl;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private Node createComboBox(Setting setting) throws NoSuchFieldException, IllegalAccessException {
ListProperty<?> listProp = (ListProperty<?>) setting.getProperty();
ComboBox<Object> comboBox = new ComboBox(listProp);
// Field field = Settings.class.getField(setting.getKey());
// Object value = field.get(Config.getInstance().getSettings());
// if (StringUtil.isNotBlank(value.toString())) {
// if (setting.getConverter() != null) {
// comboBox.getSelectionModel().select(setting.getConverter().convertTo(value));
// } else {
// comboBox.getSelectionModel().select(value);
// }
// }
// comboBox.valueProperty().addListener((obs, oldV, newV) -> saveValue(() -> {
// if (setting.getConverter() != null) {
// field.set(settings, setting.getConverter().convertFrom(newV));
// } else {
// field.set(settings, newV);
// }
// config.save();
// }));
return comboBox;
@SuppressWarnings({ "rawtypes", "unchecked" })
private Node createComboBox(Setting setting) {
ListProperty<?> listProp = (ListProperty<?>) setting.getProperty();
ComboBox<Object> comboBox = new ComboBox(listProp);
return comboBox;
}
}
}

View File

@ -94,24 +94,24 @@ public class ActionSettingsPanel extends GridPane {
setVgap(10);
setPadding(new Insets(20, 10, 10, 10));
Label headline = new Label("Events & Actions");
var headline = new Label("Events & Actions");
headline.getStyleClass().add("settings-group-label");
add(headline, 0, 0);
actionTable = createActionTable();
ScrollPane scrollPane = new ScrollPane(actionTable);
var scrollPane = new ScrollPane(actionTable);
scrollPane.setFitToHeight(true);
scrollPane.setFitToWidth(true);
scrollPane.setStyle("-fx-background-color: -fx-background");
add(scrollPane, 0, 1);
GridPane.setHgrow(scrollPane, Priority.ALWAYS);
Button add = new Button("Add");
var add = new Button("Add");
add.setOnAction(this::add);
Button delete = new Button("Delete");
var delete = new Button("Delete");
delete.setOnAction(this::delete);
delete.setDisable(true);
HBox buttons = new HBox(5, add, delete);
var buttons = new HBox(5, add, delete);
buttons.setStyle("-fx-background-color: -fx-background"); // workaround so that the buttons don't shrink
add(buttons, 0, 2);
@ -119,15 +119,15 @@ public class ActionSettingsPanel extends GridPane {
}
private void add(ActionEvent evt) {
Pane actionPane = createActionPane();
Stage dialog = new Stage();
var actionPane = createActionPane();
var dialog = new Stage();
dialog.initModality(Modality.APPLICATION_MODAL);
dialog.initOwner(getScene().getWindow());
dialog.setTitle("New Action");
InputStream icon = getClass().getResourceAsStream("/icon.png");
dialog.getIcons().add(new Image(icon));
Wizard root = new Wizard(dialog, this::validateSettings, actionPane);
Scene scene = new Scene(root, 800, 540);
var root = new Wizard(dialog, this::validateSettings, actionPane);
var scene = new Scene(root, 800, 540);
scene.getStylesheets().addAll(getScene().getStylesheets());
dialog.setScene(scene);
centerOnParent(dialog);
@ -138,58 +138,58 @@ public class ActionSettingsPanel extends GridPane {
}
private void createEventHandler() {
EventHandlerConfiguration config = new EventHandlerConfiguration();
var config = new EventHandlerConfiguration();
config.setName(name.getText());
config.setEvent(event.getValue());
if(event.getValue() == Event.Type.MODEL_STATUS_CHANGED) {
PredicateConfiguration pc = new PredicateConfiguration();
var pc = new PredicateConfiguration();
pc.setType(ModelStatePredicate.class.getName());
pc.getConfiguration().put("state", modelState.getValue().name());
pc.setName("state = " + modelState.getValue().toString());
config.getPredicates().add(pc);
} else if(event.getValue() == Event.Type.RECORDING_STATUS_CHANGED) {
PredicateConfiguration pc = new PredicateConfiguration();
var pc = new PredicateConfiguration();
pc.setType(RecordingStatePredicate.class.getName());
pc.getConfiguration().put("state", recordingState.getValue().name());
pc.setName("state = " + recordingState.getValue().toString());
config.getPredicates().add(pc);
} else if(event.getValue() == Event.Type.NO_SPACE_LEFT) {
PredicateConfiguration pc = new PredicateConfiguration();
var pc = new PredicateConfiguration();
pc.setType(MatchAllPredicate.class.getName());
pc.setName("no space left");
config.getPredicates().add(pc);
}
if(!modelSelectionPane.isAllSelected()) {
PredicateConfiguration pc = new PredicateConfiguration();
var pc = new PredicateConfiguration();
pc.setType(ModelPredicate.class.getName());
pc.setModels(modelSelectionPane.getSelectedItems());
pc.setName("model is one of:" + modelSelectionPane.getSelectedItems());
config.getPredicates().add(pc);
}
if(showNotification.isSelected()) {
ActionConfiguration ac = new ActionConfiguration();
var ac = new ActionConfiguration();
ac.setType(ShowNotification.class.getName());
ac.setName("show notification");
config.getActions().add(ac);
}
if(playSound.isSelected()) {
ActionConfiguration ac = new ActionConfiguration();
var ac = new ActionConfiguration();
ac.setType(PlaySound.class.getName());
File file = new File(sound.fileProperty().get());
var file = new File(sound.fileProperty().get());
ac.getConfiguration().put("file", file.getAbsolutePath());
ac.setName("play " + file.getName());
config.getActions().add(ac);
}
if(executeProgram.isSelected()) {
ActionConfiguration ac = new ActionConfiguration();
var ac = new ActionConfiguration();
ac.setType(ExecuteProgram.class.getName());
File file = new File(program.fileProperty().get());
var file = new File(program.fileProperty().get());
ac.getConfiguration().put("file", file.getAbsolutePath());
ac.setName("execute " + file.getName());
config.getActions().add(ac);
}
EventHandler handler = new EventHandler(config);
var handler = new EventHandler(config);
EventBusHolder.register(handler);
Config.getInstance().getSettings().eventHandlers.add(config);
actionTable.getItems().add(config);
@ -229,7 +229,7 @@ public class ActionSettingsPanel extends GridPane {
modelState.prefWidthProperty().bind(event.widthProperty());
name.prefWidthProperty().bind(event.widthProperty());
int row = 0;
var row = 0;
layout.add(new Label("Name"), 0, row);
layout.add(name, 1, row++);
@ -243,7 +243,7 @@ public class ActionSettingsPanel extends GridPane {
layout.add(event, 1, row++);
event.getSelectionModel().selectedItemProperty().addListener((obs, oldV, newV) -> {
boolean modelRelatedStuffDisabled = false;
var modelRelatedStuffDisabled = false;
if(newV == Event.Type.NO_SPACE_LEFT) {
modelRelatedStuffDisabled = true;
modelSelectionPane.selectAll();
@ -265,7 +265,7 @@ public class ActionSettingsPanel extends GridPane {
layout.add(createSeparator(), 0, row++);
Label l = new Label("Models");
var l = new Label("Models");
layout.add(l, 0, row);
modelSelectionPane = new ListSelectionPane<>(recorder.getModels(), Collections.emptyList());
layout.add(modelSelectionPane, 1, row++);
@ -278,8 +278,8 @@ public class ActionSettingsPanel extends GridPane {
layout.add(showNotification, 0, row);
layout.add(testNotification, 1, row++);
testNotification.setOnAction(evt -> {
DateTimeFormatter format = DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM);
ZonedDateTime time = ZonedDateTime.now();
var format = DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM);
var time = ZonedDateTime.now();
DesktopIntegration.notification(CamrecApplication.title, "Test Notification", "Oi, what's up! " + format.format(time));
});
testNotification.disableProperty().bind(showNotification.selectedProperty().not());
@ -306,12 +306,12 @@ public class ActionSettingsPanel extends GridPane {
}
private Node createSeparator() {
Separator divider = new Separator(Orientation.HORIZONTAL);
var divider = new Separator(Orientation.HORIZONTAL);
GridPane.setHgrow(divider, Priority.ALWAYS);
GridPane.setFillWidth(divider, true);
GridPane.setColumnSpan(divider, 2);
int tb = 20;
int lr = 0;
var tb = 20;
var lr = 0;
GridPane.setMargin(divider, new Insets(tb, lr, tb, lr));
return divider;
}

View File

@ -61,7 +61,7 @@ public class ColorSettingsPane extends HBox {
}
private String toWeb(Color value) {
StringBuilder sb = new StringBuilder("#");
var sb = new StringBuilder("#");
sb.append(toHex((int) (value.getRed() * 255)));
sb.append(toHex((int) (value.getGreen() * 255)));
sb.append(toHex((int) (value.getBlue() * 255)));
@ -72,7 +72,7 @@ public class ColorSettingsPane extends HBox {
}
private CharSequence toHex(int v) {
StringBuilder sb = new StringBuilder();
var sb = new StringBuilder();
if(v < 16) {
sb.append('0');
}

View File

@ -18,13 +18,13 @@ public class CreateContactSheetPaneFactory extends AbstractPostProcessingPaneFac
@Override
public Preferences doCreatePostProcessorPane(PostProcessor pp) {
SimpleStringProperty totalSize = new SimpleStringProperty(null, TOTAL_SIZE, pp.getConfig().getOrDefault(TOTAL_SIZE, "1920"));
SimpleStringProperty padding = new SimpleStringProperty(null, PADDING, pp.getConfig().getOrDefault(PADDING, "4"));
SimpleStringProperty cols = new SimpleStringProperty(null, COLS, pp.getConfig().getOrDefault(COLS, "8"));
SimpleStringProperty rows = new SimpleStringProperty(null, ROWS, pp.getConfig().getOrDefault(ROWS, "7"));
SimpleStringProperty filename = new SimpleStringProperty(null, FILENAME, pp.getConfig().getOrDefault(FILENAME, "contactsheet.jpg"));
var totalSize = new SimpleStringProperty(null, TOTAL_SIZE, pp.getConfig().getOrDefault(TOTAL_SIZE, "1920"));
var padding = new SimpleStringProperty(null, PADDING, pp.getConfig().getOrDefault(PADDING, "4"));
var cols = new SimpleStringProperty(null, COLS, pp.getConfig().getOrDefault(COLS, "8"));
var rows = new SimpleStringProperty(null, ROWS, pp.getConfig().getOrDefault(ROWS, "7"));
var filename = new SimpleStringProperty(null, FILENAME, pp.getConfig().getOrDefault(FILENAME, "contactsheet.jpg"));
background = new SimpleStringProperty(null, BACKGROUND, pp.getConfig().getOrDefault(BACKGROUND, "0x333333"));
SimpleBooleanProperty burnTimestamp = new SimpleBooleanProperty(null, BURN_IN_TIMESTAMP,
var burnTimestamp = new SimpleBooleanProperty(null, BURN_IN_TIMESTAMP,
Boolean.valueOf(pp.getConfig().getOrDefault(BURN_IN_TIMESTAMP, TRUE.toString())));
properties.add(totalSize);
properties.add(padding);
@ -34,8 +34,8 @@ public class CreateContactSheetPaneFactory extends AbstractPostProcessingPaneFac
properties.add(background);
properties.add(burnTimestamp);
Setting backgroundSetting = Setting.of("", background, "Hexadecimal value of the background color for the space between the thumbnails");
Preferences prefs = Preferences.of(new MapPreferencesStorage(),
var backgroundSetting = Setting.of("", background, "Hexadecimal value of the background color for the space between the thumbnails");
var prefs = Preferences.of(new MapPreferencesStorage(),
Category.of(pp.getName(),
Setting.of("Total Width", totalSize, "Total width of the generated contact sheet"),
Setting.of("Padding", padding, "Padding between the thumbnails"),
@ -59,8 +59,8 @@ public class CreateContactSheetPaneFactory extends AbstractPostProcessingPaneFac
}
private ColorPicker createColorPicker(String hexColor) {
Color preselection = Color.web(hexColor);
ColorPicker colorPicker = new ColorPicker(preselection);
var preselection = Color.web(hexColor);
var colorPicker = new ColorPicker(preselection);
colorPicker.setOnAction(e -> background.set(colorPicker.getValue().toString()));
return colorPicker;
}

View File

@ -1,7 +1,6 @@
package ctbrec.ui.settings;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@ -71,55 +70,55 @@ public class CtbrecPreferencesStorage implements PreferencesStorage {
}
@Override
public Node createGui(Setting setting) throws Exception {
config.disableSaving();
try {
Property<?> prop = setting.getProperty();
if (prop instanceof ExclusiveSelectionProperty) {
return createRadioGroup(setting);
} else if (prop instanceof SimpleRangeProperty) {
return createRangeSlider(setting);
} else if (prop instanceof SimpleDirectoryProperty) {
return createDirectorySelector(setting);
} else if (prop instanceof SimpleFileProperty) {
return createFileSelector(setting);
} else if (prop instanceof IntegerProperty) {
return createIntegerProperty(setting);
} else if (prop instanceof LongProperty) {
return createLongProperty(setting);
} else if (prop instanceof BooleanProperty) {
return createBooleanProperty(setting);
} else if (prop instanceof ListProperty) {
return createComboBox(setting);
} else if (prop instanceof StringProperty) {
return createStringProperty(setting);
} else {
return new Label("Unsupported Type for key " + setting.getKey() + ": " + setting.getProperty());
}
} finally {
config.enableSaving();
}
public Node createGui(Setting setting) throws NoSuchFieldException, IllegalAccessException {
config.disableSaving();
try {
Property<?> prop = setting.getProperty();
if (prop instanceof ExclusiveSelectionProperty) {
return createRadioGroup(setting);
} else if (prop instanceof SimpleRangeProperty) {
return createRangeSlider(setting);
} else if (prop instanceof SimpleDirectoryProperty) {
return createDirectorySelector(setting);
} else if (prop instanceof SimpleFileProperty) {
return createFileSelector(setting);
} else if (prop instanceof IntegerProperty) {
return createIntegerProperty(setting);
} else if (prop instanceof LongProperty) {
return createLongProperty(setting);
} else if (prop instanceof BooleanProperty) {
return createBooleanProperty(setting);
} else if (prop instanceof ListProperty) {
return createComboBox(setting);
} else if (prop instanceof StringProperty) {
return createStringProperty(setting);
} else {
return new Label("Unsupported Type for key " + setting.getKey() + ": " + setting.getProperty());
}
} finally {
config.enableSaving();
}
}
private Node createRadioGroup(Setting setting) {
ExclusiveSelectionProperty prop = (ExclusiveSelectionProperty) setting.getProperty();
ToggleGroup toggleGroup = new ToggleGroup();
RadioButton optionA = new RadioButton(prop.getOptionA());
var toggleGroup = new ToggleGroup();
var optionA = new RadioButton(prop.getOptionA());
optionA.setSelected(prop.getValue());
optionA.setToggleGroup(toggleGroup);
RadioButton optionB = new RadioButton(prop.getOptionB());
var optionB = new RadioButton(prop.getOptionB());
optionB.setSelected(!optionA.isSelected());
optionB.setToggleGroup(toggleGroup);
optionA.selectedProperty().bindBidirectional(prop);
prop.addListener((obs, oldV, newV) -> saveValue(() -> {
Field field = Settings.class.getField(setting.getKey());
field.set(settings, newV);
var field = Settings.class.getField(setting.getKey());
field.set(settings, newV); // NOSONAR
if (setting.doesNeedRestart() && !Objects.equals(oldV, newV)) {
runRestartRequiredCallback();
}
config.save();
}));
HBox row = new HBox();
var row = new HBox();
row.getChildren().addAll(optionA, optionB);
HBox.setMargin(optionA, new Insets(5));
HBox.setMargin(optionB, new Insets(5));
@ -151,22 +150,22 @@ public class CtbrecPreferencesStorage implements PreferencesStorage {
resolutionRange.setHigh(highValue >= 0 ? highValue : values.get(values.size() - 1));
resolutionRange.getLow().addListener((obs, o, n) -> saveValue(() -> {
int newV = labels.get(n.intValue());
Field field = Settings.class.getField(rangeProperty.getLowKey());
field.set(settings, newV);
var field = Settings.class.getField(rangeProperty.getLowKey());
field.set(settings, newV); // NOSONAR
config.save();
}));
resolutionRange.getHigh().addListener((obs, o, n) -> saveValue(() -> {
int newV = labels.get(n.intValue());
Field field = Settings.class.getField(rangeProperty.getHighKey());
field.set(settings, newV);
var field = Settings.class.getField(rangeProperty.getHighKey());
field.set(settings, newV); // NOSONAR
config.save();
}));
return resolutionRange;
}
private int getRangeSliderValue(List<Integer> values, List<Integer> labels, int value) {
for (int i = 0; i < labels.size(); i++) {
int label = labels.get(i).intValue();
for (var i = 0; i < labels.size(); i++) {
var label = labels.get(i).intValue();
if (label == value) {
return values.get(i);
}
@ -175,13 +174,13 @@ public class CtbrecPreferencesStorage implements PreferencesStorage {
}
private Node createFileSelector(Setting setting) {
ProgramSelectionBox programSelector = new ProgramSelectionBox("");
var programSelector = new ProgramSelectionBox("");
programSelector.fileProperty().addListener((obs, o, n) -> saveValue(() -> {
String path = n;
Field field = Settings.class.getField(setting.getKey());
var field = Settings.class.getField(setting.getKey());
String oldValue = (String) field.get(settings);
if (!Objects.equals(path, oldValue)) {
field.set(settings, path);
field.set(settings, path); // NOSONAR
if (setting.doesNeedRestart()) {
runRestartRequiredCallback();
}
@ -194,14 +193,14 @@ public class CtbrecPreferencesStorage implements PreferencesStorage {
}
private Node createDirectorySelector(Setting setting) {
DirectorySelectionBox directorySelector = new DirectorySelectionBox("");
var directorySelector = new DirectorySelectionBox("");
directorySelector.prefWidth(400);
directorySelector.fileProperty().addListener((obs, o, n) -> saveValue(() -> {
String path = n;
Field field = Settings.class.getField(setting.getKey());
var field = Settings.class.getField(setting.getKey());
String oldValue = (String) field.get(settings);
if (!Objects.equals(path, oldValue)) {
field.set(settings, path);
field.set(settings, path); // NOSONAR
if (setting.doesNeedRestart()) {
runRestartRequiredCallback();
}
@ -214,10 +213,10 @@ public class CtbrecPreferencesStorage implements PreferencesStorage {
}
private Node createStringProperty(Setting setting) {
TextField ctrl = new TextField();
var ctrl = new TextField();
ctrl.textProperty().addListener((obs, oldV, newV) -> saveValue(() -> {
Field field = Settings.class.getField(setting.getKey());
field.set(settings, newV);
var field = Settings.class.getField(setting.getKey());
field.set(settings, newV); // NOSONAR
if (setting.doesNeedRestart() && !Objects.equals(oldV, newV)) {
runRestartRequiredCallback();
}
@ -230,14 +229,14 @@ public class CtbrecPreferencesStorage implements PreferencesStorage {
@SuppressWarnings("unchecked")
private Node createIntegerProperty(Setting setting) {
TextField ctrl = new TextField();
var ctrl = new TextField();
ctrl.textProperty().addListener((obs, oldV, newV) -> saveValue(() -> {
if (!newV.matches("\\d*")) {
ctrl.setText(newV.replaceAll(PATTERN_NOT_A_DIGIT, ""));
}
if (!ctrl.getText().isEmpty()) {
Field field = Settings.class.getField(setting.getKey());
field.set(settings, Integer.parseInt(ctrl.getText()));
var field = Settings.class.getField(setting.getKey());
field.set(settings, Integer.parseInt(ctrl.getText())); // NOSONAR
if (setting.doesNeedRestart() && !Objects.equals(oldV, newV) && prefs != null) {
runRestartRequiredCallback();
}
@ -251,18 +250,18 @@ public class CtbrecPreferencesStorage implements PreferencesStorage {
@SuppressWarnings("unchecked")
private Node createLongProperty(Setting setting) {
TextField ctrl = new TextField();
var ctrl = new TextField();
ctrl.textProperty().addListener((obs, oldV, newV) -> saveValue(() -> {
if (!newV.matches("\\d*")) {
ctrl.setText(newV.replaceAll(PATTERN_NOT_A_DIGIT, ""));
}
if (!ctrl.getText().isEmpty()) {
long value = Long.parseLong(ctrl.getText());
var value = Long.parseLong(ctrl.getText());
if (setting.getConverter() != null) {
value = (long) setting.getConverter().convertFrom(value);
}
Field field = Settings.class.getField(setting.getKey());
field.set(settings, value);
var field = Settings.class.getField(setting.getKey());
field.set(settings, value); // NOSONAR
if (setting.doesNeedRestart() && !Objects.equals(oldV, newV)) {
runRestartRequiredCallback();
}
@ -275,10 +274,10 @@ public class CtbrecPreferencesStorage implements PreferencesStorage {
}
private Node createBooleanProperty(Setting setting) {
CheckBox ctrl = new CheckBox();
var ctrl = new CheckBox();
ctrl.selectedProperty().addListener((obs, oldV, newV) -> saveValue(() -> {
Field field = Settings.class.getField(setting.getKey());
field.set(settings, newV);
var field = Settings.class.getField(setting.getKey());
field.set(settings, newV); // NOSONAR
if (setting.doesNeedRestart() && !Objects.equals(oldV, newV)) {
runRestartRequiredCallback();
}
@ -293,7 +292,7 @@ public class CtbrecPreferencesStorage implements PreferencesStorage {
private Node createComboBox(Setting setting) throws NoSuchFieldException, IllegalAccessException {
ListProperty<?> listProp = (ListProperty<?>) setting.getProperty();
ComboBox<Object> comboBox = new ComboBox(listProp);
Field field = Settings.class.getField(setting.getKey());
var field = Settings.class.getField(setting.getKey());
Object value = field.get(settings);
if (StringUtil.isNotBlank(value.toString())) {
if (setting.getConverter() != null) {
@ -305,9 +304,9 @@ public class CtbrecPreferencesStorage implements PreferencesStorage {
comboBox.valueProperty().addListener((obs, oldV, newV) -> saveValue(() -> {
LOG.debug("Saving setting {}", setting.getKey());
if (setting.getConverter() != null) {
field.set(settings, setting.getConverter().convertFrom(newV));
field.set(settings, setting.getConverter().convertFrom(newV)); // NOSONAR
} else {
field.set(settings, newV);
field.set(settings, newV); // NOSONAR
}
if (setting.doesNeedRestart() && !Objects.equals(oldV, newV)) {
runRestartRequiredCallback();
@ -330,6 +329,6 @@ public class CtbrecPreferencesStorage implements PreferencesStorage {
@FunctionalInterface
private interface Exec {
public void run() throws Exception;
public void run() throws IllegalAccessException, IOException, NoSuchFieldException;
}
}

View File

@ -11,7 +11,7 @@ public class DeleteTooShortPaneFactory extends AbstractPostProcessingPaneFactory
@Override
public Preferences doCreatePostProcessorPane(PostProcessor pp) {
SimpleStringProperty minimumLengthInSeconds = new SimpleStringProperty(null, DeleteTooShort.MIN_LEN_IN_SECS, pp.getConfig().getOrDefault(DeleteTooShort.MIN_LEN_IN_SECS, "10"));
var minimumLengthInSeconds = new SimpleStringProperty(null, DeleteTooShort.MIN_LEN_IN_SECS, pp.getConfig().getOrDefault(DeleteTooShort.MIN_LEN_IN_SECS, "10"));
properties.add(minimumLengthInSeconds);
return Preferences.of(new MapPreferencesStorage(),

View File

@ -2,7 +2,6 @@ package ctbrec.ui.settings;
import static javafx.scene.control.ButtonType.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Type;
@ -57,7 +56,7 @@ public class IgnoreList extends GridPane {
setVgap(10);
setPadding(new Insets(20, 10, 10, 10));
Label headline = new Label("Ignore List");
var headline = new Label("Ignore List");
headline.getStyleClass().add("settings-group-label");
add(headline, 0, 0);
@ -71,13 +70,13 @@ public class IgnoreList extends GridPane {
add(ignoreListView, 0, 1);
GridPane.setHgrow(ignoreListView, Priority.ALWAYS);
Button remove = new Button("Remove");
var remove = new Button("Remove");
remove.setOnAction(evt -> removeSelectedModels());
Button exportIgnoreList = new Button("Export");
var exportIgnoreList = new Button("Export");
exportIgnoreList.setOnAction(e -> exportIgnoreList());
Button importIgnoreList = new Button("Import");
var importIgnoreList = new Button("Import");
importIgnoreList.setOnAction(e -> importIgnoreList());
HBox buttons = new HBox(10, remove, exportIgnoreList, importIgnoreList);
var buttons = new HBox(10, remove, exportIgnoreList, importIgnoreList);
add(buttons, 0, 2);
buttons.setStyle("-fx-background-color: -fx-background"); // workaround so that the buttons don't shrink
}
@ -85,7 +84,7 @@ public class IgnoreList extends GridPane {
private void removeSelectedModels() {
List<String> selectedModels = ignoreListView.getSelectionModel().getSelectedItems();
if (selectedModels.isEmpty()) {
return;
return; // NOSONAR
} else {
Config.getInstance().getSettings().ignoredModels.removeAll(selectedModels);
ignoreListView.getItems().removeAll(selectedModels);
@ -110,16 +109,16 @@ public class IgnoreList extends GridPane {
}
private void exportIgnoreList() {
FileChooser chooser = new FileChooser();
var chooser = new FileChooser();
chooser.setTitle("Export ignore list");
chooser.setInitialFileName("ctbrec-ignorelist.json");
File file = chooser.showSaveDialog(null);
var file = chooser.showSaveDialog(null);
if (file != null) {
Moshi moshi = new Moshi.Builder().add(Model.class, new ModelJsonAdapter(sites)).build();
var moshi = new Moshi.Builder().add(Model.class, new ModelJsonAdapter(sites)).build();
Type modelListType = Types.newParameterizedType(List.class, String.class);
JsonAdapter<List<String>> adapter = moshi.adapter(modelListType);
adapter = adapter.indent(" ");
try (FileOutputStream out = new FileOutputStream(file)) {
try (var out = new FileOutputStream(file)) {
String json = adapter.toJson(Config.getInstance().getSettings().ignoredModels);
out.write(json.getBytes(StandardCharsets.UTF_8));
} catch (IOException e) {
@ -129,20 +128,20 @@ public class IgnoreList extends GridPane {
}
private void importIgnoreList() {
FileChooser chooser = new FileChooser();
var chooser = new FileChooser();
chooser.setTitle("Import ignore list");
File file = chooser.showOpenDialog(null);
var file = chooser.showOpenDialog(null);
if (file != null) {
Moshi moshi = new Moshi.Builder().add(Model.class, new ModelJsonAdapter(sites)).build();
var moshi = new Moshi.Builder().add(Model.class, new ModelJsonAdapter(sites)).build();
Type modelListType = Types.newParameterizedType(List.class, String.class);
JsonAdapter<List<String>> adapter = moshi.adapter(modelListType);
try {
byte[] fileContent = Files.readAllBytes(file.toPath());
List<String> ignoredModels = adapter.fromJson(new String(fileContent, StandardCharsets.UTF_8));
boolean confirmed = true;
var confirmed = true;
if (!Config.getInstance().getSettings().ignoredModels.isEmpty()) {
String msg = "This will replace the existing ignore list! Continue?";
AutosizeAlert confirm = new AutosizeAlert(AlertType.CONFIRMATION, msg, getScene(), YES, NO);
var msg = "This will replace the existing ignore list! Continue?";
var confirm = new AutosizeAlert(AlertType.CONFIRMATION, msg, getScene(), YES, NO);
confirm.setTitle("Import ignore list");
confirm.setHeaderText("Overwrite ignore list");
confirm.showAndWait();

View File

@ -38,7 +38,7 @@ public class ListSelectionPane<T extends Comparable<T>> extends GridPane {
ObservableList<T> obsAvail = FXCollections.observableArrayList(available);
ObservableList<T> obsSel = FXCollections.observableArrayList(selected);
for (Iterator<T> iterator = obsAvail.iterator(); iterator.hasNext();) {
T t = iterator.next();
var t = iterator.next();
if(obsSel.contains(t)) {
iterator.remove();
}
@ -52,13 +52,13 @@ public class ListSelectionPane<T extends Comparable<T>> extends GridPane {
}
private void createGui() {
Label labelAvailable = new Label("Available");
Label labelSelected = new Label("Selected");
var labelAvailable = new Label("Available");
var labelSelected = new Label("Selected");
add(labelAvailable, 0, 0);
add(availableListView, 0, 1);
VBox buttonBox = new VBox(5);
var buttonBox = new VBox(5);
buttonBox.getChildren().add(addModel);
buttonBox.getChildren().add(removeModel);
buttonBox.setAlignment(Pos.CENTER);

View File

@ -11,7 +11,7 @@ public class MoverPaneFactory extends AbstractPostProcessingPaneFactory {
@Override
public Preferences doCreatePostProcessorPane(PostProcessor pp) {
SimpleStringProperty pathTemplate = new SimpleStringProperty(null, Move.PATH_TEMPLATE, pp.getConfig().getOrDefault(Move.PATH_TEMPLATE, Move.DEFAULT));
var pathTemplate = new SimpleStringProperty(null, Move.PATH_TEMPLATE, pp.getConfig().getOrDefault(Move.PATH_TEMPLATE, Move.DEFAULT));
properties.add(pathTemplate);
return Preferences.of(new MapPreferencesStorage(),

View File

@ -1,7 +1,21 @@
package ctbrec.ui.settings;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.Optional;
import ctbrec.Config;
import ctbrec.recorder.postprocessing.*;
import ctbrec.recorder.postprocessing.Copy;
import ctbrec.recorder.postprocessing.CreateContactSheet;
import ctbrec.recorder.postprocessing.DeleteOriginal;
import ctbrec.recorder.postprocessing.DeleteTooShort;
import ctbrec.recorder.postprocessing.Move;
import ctbrec.recorder.postprocessing.PostProcessor;
import ctbrec.recorder.postprocessing.RemoveKeepFile;
import ctbrec.recorder.postprocessing.Remux;
import ctbrec.recorder.postprocessing.Rename;
import ctbrec.recorder.postprocessing.Script;
import ctbrec.ui.controls.Dialogs;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
@ -16,25 +30,20 @@ import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.Optional;
public class PostProcessingStepPanel extends GridPane {
private final Config config;
private static final Class<?>[] POST_PROCESSOR_CLASSES = new Class<?>[]{ // @formatter: off
Copy.class,
Rename.class,
Move.class,
Remux.class,
Script.class,
DeleteOriginal.class,
DeleteTooShort.class,
RemoveKeepFile.class,
CreateContactSheet.class
Copy.class,
Rename.class,
Move.class,
Remux.class,
Script.class,
DeleteOriginal.class,
DeleteTooShort.class,
RemoveKeepFile.class,
CreateContactSheet.class
}; // @formatter: on
ListView<PostProcessor> stepListView;
@ -61,7 +70,7 @@ public class PostProcessingStepPanel extends GridPane {
add = createAddButton();
remove = createRemoveButton();
edit = createEditButton();
VBox buttons = new VBox(5, add, edit, up, down, remove);
var buttons = new VBox(5, add, edit, up, down, remove);
stepList = FXCollections.observableList(config.getSettings().postProcessors);
stepList.addListener((ListChangeListener<PostProcessor>) change -> {
@ -78,7 +87,7 @@ public class PostProcessingStepPanel extends GridPane {
add(buttons, 1, 0);
stepListView.getSelectionModel().selectedIndexProperty().addListener((obs, oldV, newV) -> {
int idx = newV.intValue();
var idx = newV.intValue();
boolean noSelection = idx == -1;
up.setDisable(noSelection || idx == 0);
down.setDisable(noSelection || idx == stepList.size() - 1);
@ -88,7 +97,7 @@ public class PostProcessingStepPanel extends GridPane {
}
private Button createUpButton() {
Button button = createButton("\u25B4", "Move step up");
var button = createButton("\u25B4", "Move step up");
button.setOnAction(evt -> {
int idx = stepListView.getSelectionModel().getSelectedIndex();
PostProcessor selectedItem = stepListView.getSelectionModel().getSelectedItem();
@ -100,7 +109,7 @@ public class PostProcessingStepPanel extends GridPane {
}
private Button createDownButton() {
Button button = createButton("\u25BE", "Move step down");
var button = createButton("\u25BE", "Move step down");
button.setOnAction(evt -> {
int idx = stepListView.getSelectionModel().getSelectedIndex();
PostProcessor selectedItem = stepListView.getSelectionModel().getSelectedItem();
@ -112,7 +121,7 @@ public class PostProcessingStepPanel extends GridPane {
}
private Button createAddButton() {
Button button = createButton("+", "Add a new step");
var button = createButton("+", "Add a new step");
button.setDisable(false);
button.setOnAction(evt -> {
PostProcessor[] options = createOptions();
@ -122,7 +131,7 @@ public class PostProcessingStepPanel extends GridPane {
choice.setResizable(true);
choice.setWidth(600);
choice.getDialogPane().setMinWidth(400);
Stage stage = (Stage) choice.getDialogPane().getScene().getWindow();
var stage = (Stage) choice.getDialogPane().getScene().getWindow();
stage.getScene().getStylesheets().addAll(getScene().getStylesheets());
InputStream icon = Dialogs.class.getResourceAsStream("/icon.png");
stage.getIcons().add(new Image(icon));
@ -144,8 +153,8 @@ public class PostProcessingStepPanel extends GridPane {
private PostProcessor[] createOptions() {
try {
PostProcessor[] options = new PostProcessor[POST_PROCESSOR_CLASSES.length];
for (int i = 0; i < POST_PROCESSOR_CLASSES.length; i++) {
var options = new PostProcessor[POST_PROCESSOR_CLASSES.length];
for (var i = 0; i < POST_PROCESSOR_CLASSES.length; i++) {
Class<?> cls = POST_PROCESSOR_CLASSES[i];
PostProcessor pp;
pp = (PostProcessor) cls.getDeclaredConstructor().newInstance();
@ -160,7 +169,7 @@ public class PostProcessingStepPanel extends GridPane {
}
private Button createRemoveButton() {
Button button = createButton("-", "Remove selected step");
var button = createButton("-", "Remove selected step");
button.setOnAction(evt -> {
PostProcessor selectedItem = stepListView.getSelectionModel().getSelectedItem();
if (selectedItem != null) {
@ -171,7 +180,7 @@ public class PostProcessingStepPanel extends GridPane {
}
private Button createEditButton() {
Button button = createButton("\u270E", "Edit selected step");
var button = createButton("\u270E", "Edit selected step");
button.setOnAction(evt -> {
PostProcessor selectedItem = stepListView.getSelectionModel().getSelectedItem();
PostProcessingDialogFactory.openEditDialog(selectedItem, getScene(), stepList);
@ -182,7 +191,7 @@ public class PostProcessingStepPanel extends GridPane {
}
private Button createButton(String text, String tooltip) {
Button b = new Button(text);
var b = new Button(text);
b.setTooltip(new Tooltip(tooltip));
b.setDisable(true);
b.setPrefSize(32, 32);

View File

@ -11,8 +11,8 @@ public class RemuxerPaneFactory extends AbstractPostProcessingPaneFactory {
@Override
public Preferences doCreatePostProcessorPane(PostProcessor pp) {
SimpleStringProperty ffmpegParams = new SimpleStringProperty(null, Remux.FFMPEG_ARGS, pp.getConfig().getOrDefault(Remux.FFMPEG_ARGS, "-c:v copy -c:a copy -movflags faststart -y -f mp4"));
SimpleStringProperty fileExt = new SimpleStringProperty(null, Remux.FILE_EXT, pp.getConfig().getOrDefault(Remux.FILE_EXT, "mp4"));
var ffmpegParams = new SimpleStringProperty(null, Remux.FFMPEG_ARGS, pp.getConfig().getOrDefault(Remux.FFMPEG_ARGS, "-c:v copy -c:a copy -movflags faststart -y -f mp4"));
var fileExt = new SimpleStringProperty(null, Remux.FILE_EXT, pp.getConfig().getOrDefault(Remux.FILE_EXT, "mp4"));
properties.add(ffmpegParams);
properties.add(fileExt);

View File

@ -11,7 +11,7 @@ public class RenamerPaneFactory extends AbstractPostProcessingPaneFactory {
@Override
public Preferences doCreatePostProcessorPane(PostProcessor pp) {
SimpleStringProperty fileTemplate = new SimpleStringProperty(null, Rename.FILE_NAME_TEMPLATE, pp.getConfig().getOrDefault(Rename.FILE_NAME_TEMPLATE, Rename.DEFAULT));
var fileTemplate = new SimpleStringProperty(null, Rename.FILE_NAME_TEMPLATE, pp.getConfig().getOrDefault(Rename.FILE_NAME_TEMPLATE, Rename.DEFAULT));
properties.add(fileTemplate);
return Preferences.of(new MapPreferencesStorage(),

View File

@ -11,8 +11,8 @@ public class ScriptPaneFactory extends AbstractPostProcessingPaneFactory {
@Override
public Preferences doCreatePostProcessorPane(PostProcessor pp) {
SimpleStringProperty script = new SimpleStringProperty(null, Script.SCRIPT_EXECUTABLE, pp.getConfig().getOrDefault(Script.SCRIPT_EXECUTABLE, "c:\\users\\johndoe\\somescript"));
SimpleStringProperty params = new SimpleStringProperty(null, Script.SCRIPT_PARAMS, pp.getConfig().getOrDefault(Script.SCRIPT_PARAMS, "${absolutePath}"));
var script = new SimpleStringProperty(null, Script.SCRIPT_EXECUTABLE, pp.getConfig().getOrDefault(Script.SCRIPT_EXECUTABLE, "c:\\users\\johndoe\\somescript"));
var params = new SimpleStringProperty(null, Script.SCRIPT_PARAMS, pp.getConfig().getOrDefault(Script.SCRIPT_PARAMS, "${absolutePath}"));
properties.add(script);
properties.add(params);

View File

@ -203,8 +203,8 @@ public class SettingsTab extends Tab implements TabSelectionListener {
}
private void createGui() {
PostProcessingStepPanel postProcessingStepPanel = new PostProcessingStepPanel(config);
Button variablesHelpButton = createHelpButton("Variables", "http://localhost:5689/docs/PostProcessing.md#variables");
var postProcessingStepPanel = new PostProcessingStepPanel(config);
var variablesHelpButton = createHelpButton("Variables", "http://localhost:5689/docs/PostProcessing.md#variables");
ignoreList = new IgnoreList(sites);
List<Category> siteCategories = new ArrayList<>();
for (Site site : sites) {
@ -212,8 +212,8 @@ public class SettingsTab extends Tab implements TabSelectionListener {
.ifPresent(configPanel -> siteCategories.add(Category.of(site.getName(), configPanel)));
}
CtbrecPreferencesStorage storage = new CtbrecPreferencesStorage(config);
Preferences prefs = Preferences.of(storage,
var storage = new CtbrecPreferencesStorage(config);
var prefs = Preferences.of(storage,
Category.of("General",
Group.of("General",
Setting.of("User-Agent", httpUserAgent),
@ -304,15 +304,15 @@ public class SettingsTab extends Tab implements TabSelectionListener {
storage.setPreferences(prefs);
preferencesView.setMinSize(800, 400);
preferencesView.setPrefSize(1280, 960);
ScrollPane scrollPane = new ScrollPane(preferencesView);
GridPane container = new GridPane();
var scrollPane = new ScrollPane(preferencesView);
var container = new GridPane();
container.add(scrollPane, 0, 0);
GridPane.setFillWidth(scrollPane, true);
GridPane.setFillHeight(scrollPane, true);
GridPane.setHgrow(scrollPane, Priority.ALWAYS);
GridPane.setVgrow(scrollPane, Priority.ALWAYS);
StackPane stackPane = new StackPane();
var stackPane = new StackPane();
stackPane.getChildren().add(container);
restartNotification = new Label("Restart Required");
restartNotification.setVisible(false);
@ -369,7 +369,7 @@ public class SettingsTab extends Tab implements TabSelectionListener {
}
private Button createHelpButton(String text, String url) {
Button postProcessingHelpButton = new Button(text);
var postProcessingHelpButton = new Button(text);
postProcessingHelpButton.setOnAction(e -> {
new Thread(() -> {
try {
@ -446,7 +446,7 @@ public class SettingsTab extends Tab implements TabSelectionListener {
Config.getInstance().getSettings().key = key;
saveConfig();
}
TextInputDialog keyDialog = new TextInputDialog();
var keyDialog = new TextInputDialog();
keyDialog.setResizable(true);
keyDialog.setTitle("Server Authentication");
keyDialog.setHeaderText("A key has been generated");
@ -485,7 +485,7 @@ public class SettingsTab extends Tab implements TabSelectionListener {
}
public static GridPane createGridLayout() {
GridPane layout = new GridPane();
var layout = new GridPane();
layout.setPadding(new Insets(10));
layout.setHgap(5);
layout.setVgap(5);
@ -500,7 +500,7 @@ public class SettingsTab extends Tab implements TabSelectionListener {
fadeIn.setOnFinished(e -> {
Transition fadeOut = changeOpacity(restartNotification, 0);
fadeOut.setOnFinished(e2 -> restartNotification.setVisible(false));
PauseTransition pauseTransition = new PauseTransition(Duration.seconds(5));
var pauseTransition = new PauseTransition(Duration.seconds(5));
pauseTransition.setOnFinished(evt -> fadeOut.play());
pauseTransition.play();
});
@ -509,7 +509,7 @@ public class SettingsTab extends Tab implements TabSelectionListener {
private static final Duration ANIMATION_DURATION = new Duration(500);
private Transition changeOpacity(Node node, double opacity) {
FadeTransition transition = new FadeTransition(ANIMATION_DURATION, node);
var transition = new FadeTransition(ANIMATION_DURATION, node);
transition.setFromValue(node.getOpacity());
transition.setToValue(opacity);
return transition;
@ -536,8 +536,8 @@ public class SettingsTab extends Tab implements TabSelectionListener {
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
final var prime = 31;
var result = 1;
result = prime * result + value;
return result;
}
@ -590,8 +590,8 @@ public class SettingsTab extends Tab implements TabSelectionListener {
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
final var prime = 31;
var result = 1;
result = prime * result + (int) (value ^ (value >>> 32));
return result;
}

View File

@ -90,17 +90,17 @@ public class Category {
String q = filter.toLowerCase().trim();
if(hasGroups() || hasSubCategories()) {
return name.toLowerCase().contains(q)
| groupsContains(q)
| subCategoriesContains(q);
|| groupsContains(q)
|| subCategoriesContains(q);
} else {
return name.toLowerCase().contains(q)
| guiContains(q);
|| guiContains(q);
}
}
private boolean subCategoriesContains(String filter) {
boolean contains = false;
var contains = false;
if (subCategories != null) {
for (Category category : subCategories) {
if (category.contains(filter)) {
@ -112,7 +112,7 @@ public class Category {
}
private boolean groupsContains(String filter) {
boolean contains = false;
var contains = false;
if (groups != null) {
for (Group group : groups) {
if (group.contains(filter)) {
@ -131,9 +131,9 @@ public class Category {
}
private boolean nodeContains(Node node, String filter) {
boolean contains = false;
var contains = false;
if (node instanceof Pane) {
Pane pane = (Pane) node;
var pane = (Pane) node;
for (Node child : pane.getChildren()) {
contains |= nodeContains(child, filter);
}

View File

@ -34,11 +34,11 @@ public class Group {
}
public boolean contains(String filter) {
return name.toLowerCase().contains(filter) | settingsContain(filter);
return name.toLowerCase().contains(filter) || settingsContain(filter);
}
private boolean settingsContain(String filter) {
boolean contains = false;
var contains = false;
if (settings != null) {
for (Setting setting : settings) {
if (setting.contains(filter)) {

View File

@ -16,7 +16,7 @@ class HighlightingSupport {
private HighlightingSupport() {}
static void highlightMatches(Category cat, String filter) {
Node node = cat.getGuiOrElse(Label::new);
var node = cat.getGuiOrElse(Label::new);
highlightMatchess(node, filter);
if(cat.hasSubCategories()) {
for (Category sub : cat.getSubCategories()) {
@ -26,9 +26,9 @@ class HighlightingSupport {
}
static void highlightMatchess(Node node, String filter) {
boolean contains = false;
var contains = false;
if (node instanceof Pane) {
Pane pane = (Pane) node;
var pane = (Pane) node;
for (Node child : pane.getChildren()) {
highlightMatchess(child, filter);
}
@ -51,9 +51,9 @@ class HighlightingSupport {
}
private static boolean labelControlContains(Label lbl, String filter) {
boolean contains = false;
var contains = false;
if (lbl.labelForProperty().get() != null) {
Node labeledNode = lbl.labelForProperty().get();
var labeledNode = lbl.labelForProperty().get();
contains |= labeledNode.toString().toLowerCase().contains(filter);
if (labeledNode instanceof Control) {
contains |= ofNullable(((Control) labeledNode).getTooltip()).map(Tooltip::getText).orElse("").toLowerCase().contains(filter);
@ -66,7 +66,7 @@ class HighlightingSupport {
}
static void removeHighlights(Category cat) {
Node node = cat.getGuiOrElse(Label::new);
var node = cat.getGuiOrElse(Label::new);
removeHighlights(node);
if(cat.hasSubCategories()) {
for (Category sub : cat.getSubCategories()) {

View File

@ -72,17 +72,17 @@ public class Preferences {
}
public Region getView(boolean withNavigation) {
SearchBox search = new SearchBox(true);
var search = new SearchBox(true);
search.textProperty().addListener(this::filterTree);
TreeItem<Category> categoryTreeItems = createCategoryTree(categories, new TreeItem<>(), null);
categoryTree = new TreeView<>(categoryTreeItems);
categoryTree.showRootProperty().set(false);
VBox leftSide = new VBox(search, categoryTree);
var leftSide = new VBox(search, categoryTree);
VBox.setVgrow(categoryTree, Priority.ALWAYS);
VBox.setMargin(search, new Insets(2));
VBox.setMargin(categoryTree, new Insets(2));
BorderPane main = new BorderPane();
var main = new BorderPane();
if (withNavigation) {
main.setLeft(leftSide);
}
@ -149,9 +149,9 @@ public class Preferences {
}
private Node createPaneWithGroups(Category cat) throws Exception {
VBox pane = new VBox();
var pane = new VBox();
for (Group grp : cat.getGroups()) {
Label groupLabel = new Label(grp.getName());
var groupLabel = new Label(grp.getName());
groupLabel.getStyleClass().add("settings-group-label");
VBox.setMargin(groupLabel, new Insets(20, 0, 10, 20));
pane.getChildren().add(groupLabel);
@ -163,13 +163,13 @@ public class Preferences {
}
private Node createGrid(Setting[] settings) throws Exception {
GridPane pane = new GridPane();
var pane = new GridPane();
pane.setHgap(2);
pane.vgapProperty().bind(pane.hgapProperty());
int row = 0;
var row = 0;
for (Setting setting : settings) {
Node node = setting.getGui();
Label label = new Label(setting.getName());
var node = setting.getGui();
var label = new Label(setting.getName());
label.setMinHeight(34);
label.labelForProperty().set(node);
label.setTooltip(new Tooltip(setting.getName()));
@ -226,7 +226,7 @@ public class Preferences {
}
public Optional<Setting> getSetting(String key) {
SettingSearchVisitor search = new SettingSearchVisitor(key);
var search = new SettingSearchVisitor(key);
traverse(search);
return search.getResult();
}

View File

@ -9,5 +9,5 @@ public interface PreferencesStorage {
void save(Preferences preferences) throws IOException;
void load(Preferences preferences);
Node createGui(Setting setting) throws Exception;
Node createGui(Setting setting) throws NoSuchFieldException, IllegalAccessException;
}

View File

@ -3,6 +3,7 @@ package ctbrec.ui.settings.api;
import static java.util.Optional.*;
import ctbrec.StringUtil;
import ctbrec.ui.controls.Dialogs;
import javafx.beans.property.Property;
import javafx.beans.value.ChangeListener;
import javafx.scene.Node;
@ -35,13 +36,13 @@ public class Setting {
}
public static Setting of(String name, Property<?> property, String tooltip) {
Setting setting = new Setting(name, property);
var setting = new Setting(name, property);
setting.tooltip = tooltip;
return setting;
}
public static Setting of(String name, Node gui) {
Setting setting = new Setting(name, gui);
var setting = new Setting(name, gui);
return setting;
}
@ -79,12 +80,16 @@ public class Setting {
return property;
}
public Node getGui() throws Exception {
public Node getGui() {
if (gui == null) {
gui = preferencesStorage.createGui(this);
if (gui instanceof Control && StringUtil.isNotBlank(tooltip)) {
Control control = (Control) gui;
control.setTooltip(new Tooltip(tooltip));
try {
gui = preferencesStorage.createGui(this);
if (gui instanceof Control && StringUtil.isNotBlank(tooltip)) {
var control = (Control) gui;
control.setTooltip(new Tooltip(tooltip));
}
} catch (NoSuchFieldException | IllegalAccessException e) {
Dialogs.showError("Error", "Error creating settings GUI", e);
}
}
return gui;

View File

@ -9,7 +9,7 @@ import ctbrec.Config;
public abstract class AbstractConfigUI implements ConfigUI {
private static final transient Logger LOG = LoggerFactory.getLogger(AbstractConfigUI.class);
private static final Logger LOG = LoggerFactory.getLogger(AbstractConfigUI.class);
protected void save() {
try {

View File

@ -1,7 +1,6 @@
package ctbrec.ui.sites.bonga;
import ctbrec.Config;
import ctbrec.Settings;
import ctbrec.sites.bonga.BongaCams;
import ctbrec.ui.DesktopIntegration;
import ctbrec.ui.settings.SettingsTab;
@ -26,14 +25,14 @@ public class BongaCamsConfigUI extends AbstractConfigUI {
@Override
public Parent createConfigPanel() {
GridPane layout = SettingsTab.createGridLayout();
Settings settings = Config.getInstance().getSettings();
var settings = Config.getInstance().getSettings();
int row = 0;
Label l = new Label("Active");
var row = 0;
var l = new Label("Active");
layout.add(l, 0, row);
CheckBox enabled = new CheckBox();
var enabled = new CheckBox();
enabled.setSelected(!settings.disabledSites.contains(bongaCams.getName()));
enabled.setOnAction((e) -> {
enabled.setOnAction(e -> {
if(enabled.isSelected()) {
settings.disabledSites.remove(bongaCams.getName());
} else {
@ -45,7 +44,7 @@ public class BongaCamsConfigUI extends AbstractConfigUI {
layout.add(enabled, 1, row++);
layout.add(new Label("BongaCams User"), 0, row);
TextField username = new TextField(settings.bongaUsername);
var username = new TextField(settings.bongaUsername);
username.setPrefWidth(300);
username.textProperty().addListener((ob, o, n) -> {
if(!n.equals(Config.getInstance().getSettings().bongaUsername)) {
@ -60,7 +59,7 @@ public class BongaCamsConfigUI extends AbstractConfigUI {
layout.add(username, 1, row++);
layout.add(new Label("BongaCams Password"), 0, row);
PasswordField password = new PasswordField();
var password = new PasswordField();
password.setText(settings.bongaPassword);
password.textProperty().addListener((ob, o, n) -> {
if(!n.equals(Config.getInstance().getSettings().bongaPassword)) {
@ -75,7 +74,7 @@ public class BongaCamsConfigUI extends AbstractConfigUI {
layout.add(password, 1, row++);
layout.add(new Label("Bongacams Base URL"), 0, row);
TextField baseUrl = new TextField();
var baseUrl = new TextField();
baseUrl.setText(Config.getInstance().getSettings().bongacamsBaseUrl);
baseUrl.textProperty().addListener((ob, o, n) -> {
Config.getInstance().getSettings().bongacamsBaseUrl = baseUrl.getText();
@ -86,9 +85,9 @@ public class BongaCamsConfigUI extends AbstractConfigUI {
GridPane.setColumnSpan(baseUrl, 2);
layout.add(baseUrl, 1, row++);
Button createAccount = new Button("Create new Account");
createAccount.setOnAction((e) -> DesktopIntegration.open(bongaCams.getAffiliateLink()));
layout.add(createAccount, 1, row++);
var createAccount = new Button("Create new Account");
createAccount.setOnAction(e -> DesktopIntegration.open(bongaCams.getAffiliateLink()));
layout.add(createAccount, 1, row);
GridPane.setColumnSpan(createAccount, 2);
GridPane.setMargin(username, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
GridPane.setMargin(password, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));

View File

@ -7,7 +7,6 @@ import java.util.Collections;
import java.util.Objects;
import java.util.function.Consumer;
import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -32,11 +31,11 @@ public class BongaCamsElectronLoginDialog {
this.cookieJar = cookieJar;
browser = ExternalBrowser.getInstance();
try {
JSONObject config = new JSONObject();
var config = new JSONObject();
config.put("url", URL);
config.put("w", 640);
config.put("h", 480);
JSONObject msg = new JSONObject();
var msg = new JSONObject();
msg.put("config", config);
browser.run(msg, msgHandler);
} catch (InterruptedException e) {
@ -51,9 +50,9 @@ public class BongaCamsElectronLoginDialog {
if(!line.startsWith("{")) {
LOG.error("Didn't received a JSON object {}", line);
} else {
JSONObject json = new JSONObject(line);
var json = new JSONObject(line);
if(json.has("url")) {
String url = json.getString("url");
var url = json.getString("url");
if(url.endsWith("/login")) {
try {
Thread.sleep(500);
@ -66,7 +65,7 @@ public class BongaCamsElectronLoginDialog {
password = password.replace("'", "\\'");
browser.executeJavaScript("document.getElementById('log_in_password').value = '" + password + "';");
}
String[] simplify = new String[] {
var simplify = new String[] {
"$('div[class~=\"page_header\"]').css('display','none');",
"$('div[class~=\"header_bar\"]').css('display','none')",
"$('footer').css('display','none');",
@ -76,15 +75,18 @@ public class BongaCamsElectronLoginDialog {
for (String js : simplify) {
browser.executeJavaScript(js);
}
} catch(InterruptedException e) {
Thread.currentThread().interrupt();
LOG.warn("Couldn't auto fill username and password for BongaCams", e);
} catch(Exception e) {
LOG.warn("Couldn't auto fill username and password for BongaCams", e);
}
}
if(json.has("cookies")) {
JSONArray cookiesFromBrowser = json.getJSONArray("cookies");
for (int i = 0; i < cookiesFromBrowser.length(); i++) {
JSONObject cookie = cookiesFromBrowser.getJSONObject(i);
var cookiesFromBrowser = json.getJSONArray("cookies");
for (var i = 0; i < cookiesFromBrowser.length(); i++) {
var cookie = cookiesFromBrowser.getJSONObject(i);
if(cookie.getString("domain").contains(DOMAIN)) {
Builder b = new Cookie.Builder()
.path(cookie.getString("path"))

View File

@ -11,7 +11,7 @@ import ctbrec.ui.tabs.ThumbOverviewTab;
import javafx.scene.Scene;
import javafx.scene.control.Tab;
public class BongaCamsTabProvider extends TabProvider {
public class BongaCamsTabProvider implements TabProvider {
private BongaCams bongaCams;
private Recorder recorder;
@ -28,7 +28,7 @@ public class BongaCamsTabProvider extends TabProvider {
// female
String url = BongaCams.baseUrl + "/tools/listing_v3.php?livetab=female&online_only=true&is_mobile=true&offset=";
BongaCamsUpdateService updateService = new BongaCamsUpdateService(bongaCams, url);
var updateService = new BongaCamsUpdateService(bongaCams, url);
tabs.add(createTab("Female", updateService));
// male
@ -67,7 +67,7 @@ public class BongaCamsTabProvider extends TabProvider {
}
private Tab createTab(String title, PaginatedScheduledService updateService) {
ThumbOverviewTab tab = new ThumbOverviewTab(title, updateService, bongaCams);
var tab = new ThumbOverviewTab(title, updateService, bongaCams);
tab.setRecorder(recorder);
return tab;
}

View File

@ -19,7 +19,6 @@ import ctbrec.sites.bonga.BongaCamsModel;
import ctbrec.ui.tabs.PaginatedScheduledService;
import javafx.concurrent.Task;
import okhttp3.Request;
import okhttp3.Response;
public class BongaCamsUpdateService extends PaginatedScheduledService {
@ -38,48 +37,56 @@ public class BongaCamsUpdateService extends PaginatedScheduledService {
return new Task<List<Model>>() {
@Override
public List<Model> call() throws IOException {
String pageUrl = url + ((page-1) * 36);
LOG.debug("Fetching page {}", pageUrl);
Request request = new Request.Builder()
.url(pageUrl)
.addHeader(USER_AGENT, Config.getInstance().getSettings().httpUserAgent)
.addHeader(ACCEPT, MIMETYPE_APPLICATION_JSON)
.addHeader(ACCEPT, Locale.ENGLISH.getLanguage())
.addHeader(REFERER, bongaCams.getBaseUrl())
.addHeader(X_REQUESTED_WITH, XML_HTTP_REQUEST)
.build();
Response response = bongaCams.getHttpClient().execute(request);
if (response.isSuccessful()) {
String content = response.body().string();
List<Model> models = new ArrayList<>();
JSONObject json = new JSONObject(content);
//LOG.debug(json.toString(2));
if (json.optString("status").equals("success")) {
JSONArray jsonModels = json.getJSONArray("models");
for (int i = 0; i < jsonModels.length(); i++) {
JSONObject m = jsonModels.getJSONObject(i);
String name = m.optString("username");
if (name.isEmpty()) {
continue;
}
BongaCamsModel model = (BongaCamsModel) bongaCams.createModel(name);
model.mapOnlineState(m.optString("room"));
model.setOnline(m.optInt("viewers") > 0);
model.setPreview("https:" + m.getString("thumb_image").replace("{ext}", "jpg"));
if (m.has("display_name")) {
model.setDisplayName(m.getString("display_name"));
}
model.setDescription(m.optString("topic"));
models.add(model);
}
}
return models;
} else {
int code = response.code();
response.close();
throw new IOException("HTTP status " + code);
}
return loadModelList();
}
};
}
private List<Model> loadModelList() throws IOException {
String pageUrl = url + ((page-1) * 36);
LOG.debug("Fetching page {}", pageUrl);
var request = new Request.Builder()
.url(pageUrl)
.header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent)
.header(ACCEPT, MIMETYPE_APPLICATION_JSON)
.header(ACCEPT, Locale.ENGLISH.getLanguage())
.header(REFERER, bongaCams.getBaseUrl())
.header(X_REQUESTED_WITH, XML_HTTP_REQUEST)
.build();
try (var response = bongaCams.getHttpClient().execute(request)) {
if (response.isSuccessful()) {
var content = response.body().string();
List<Model> models = new ArrayList<>();
var json = new JSONObject(content);
if (json.optString("status").equals("success")) {
var jsonModels = json.getJSONArray("models");
parseModels(jsonModels, models);
}
return models;
} else {
int code = response.code();
throw new IOException("HTTP status " + code);
}
}
}
private void parseModels(JSONArray jsonModels, List<Model> models) {
for (var i = 0; i < jsonModels.length(); i++) {
var m = jsonModels.getJSONObject(i);
var name = m.optString("username");
if (name.isEmpty()) {
continue;
}
BongaCamsModel model = (BongaCamsModel) bongaCams.createModel(name);
model.mapOnlineState(m.optString("room"));
model.setOnline(m.optInt("viewers") > 0);
model.setPreview("https:" + m.getString("thumb_image").replace("{ext}", "jpg"));
if (m.has("display_name")) {
model.setDisplayName(m.getString("display_name"));
}
model.setDescription(m.optString("topic"));
models.add(model);
}
}
}

View File

@ -1,7 +1,6 @@
package ctbrec.ui.sites.cam4;
import ctbrec.Config;
import ctbrec.Settings;
import ctbrec.sites.cam4.Cam4;
import ctbrec.ui.DesktopIntegration;
import ctbrec.ui.settings.SettingsTab;
@ -25,15 +24,15 @@ public class Cam4ConfigUI extends AbstractConfigUI {
@Override
public Parent createConfigPanel() {
GridPane layout = SettingsTab.createGridLayout();
Settings settings = Config.getInstance().getSettings();
var layout = SettingsTab.createGridLayout();
var settings = Config.getInstance().getSettings();
int row = 0;
Label l = new Label("Active");
var row = 0;
var l = new Label("Active");
layout.add(l, 0, row);
CheckBox enabled = new CheckBox();
var enabled = new CheckBox();
enabled.setSelected(!settings.disabledSites.contains(cam4.getName()));
enabled.setOnAction((e) -> {
enabled.setOnAction(e -> {
if(enabled.isSelected()) {
settings.disabledSites.remove(cam4.getName());
} else {
@ -45,7 +44,7 @@ public class Cam4ConfigUI extends AbstractConfigUI {
layout.add(enabled, 1, row++);
layout.add(new Label("Cam4 User"), 0, row);
TextField username = new TextField(Config.getInstance().getSettings().cam4Username);
var username = new TextField(Config.getInstance().getSettings().cam4Username);
username.textProperty().addListener((ob, o, n) -> {
if(!n.equals(Config.getInstance().getSettings().cam4Username)) {
Config.getInstance().getSettings().cam4Username = username.getText();
@ -59,7 +58,7 @@ public class Cam4ConfigUI extends AbstractConfigUI {
layout.add(username, 1, row++);
layout.add(new Label("Cam4 Password"), 0, row);
PasswordField password = new PasswordField();
var password = new PasswordField();
password.setText(Config.getInstance().getSettings().cam4Password);
password.textProperty().addListener((ob, o, n) -> {
if(!n.equals(Config.getInstance().getSettings().cam4Password)) {
@ -73,9 +72,9 @@ public class Cam4ConfigUI extends AbstractConfigUI {
GridPane.setColumnSpan(password, 2);
layout.add(password, 1, row++);
Button createAccount = new Button("Create new Account");
createAccount.setOnAction((e) -> DesktopIntegration.open(Cam4.AFFILIATE_LINK));
layout.add(createAccount, 1, row++);
var createAccount = new Button("Create new Account");
createAccount.setOnAction(e -> DesktopIntegration.open(Cam4.AFFILIATE_LINK));
layout.add(createAccount, 1, row);
GridPane.setColumnSpan(createAccount, 2);
GridPane.setMargin(username, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
GridPane.setMargin(password, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));

View File

@ -7,7 +7,6 @@ import java.util.Collections;
import java.util.Objects;
import java.util.function.Consumer;
import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -32,11 +31,11 @@ public class Cam4ElectronLoginDialog {
this.cookieJar = cookieJar;
browser = ExternalBrowser.getInstance();
try {
JSONObject config = new JSONObject();
var config = new JSONObject();
config.put("url", URL);
config.put("w", 480);
config.put("h", 640);
JSONObject msg = new JSONObject();
var msg = new JSONObject();
msg.put("config", config);
browser.run(msg, msgHandler);
} catch (InterruptedException e) {
@ -51,9 +50,9 @@ public class Cam4ElectronLoginDialog {
if(!line.startsWith("{")) {
LOG.error("Didn't received a JSON object {}", line);
} else {
JSONObject json = new JSONObject(line);
if(json.has("url")) {
String url = json.getString("url");
var json = new JSONObject(line);
if (json.has("url")) {
var url = json.getString("url");
if(url.endsWith("/login")) {
try {
@ -76,16 +75,16 @@ public class Cam4ElectronLoginDialog {
}
if(json.has("cookies")) {
JSONArray cookiesFromBrowser = json.getJSONArray("cookies");
var cookiesFromBrowser = json.getJSONArray("cookies");
try {
for (int i = 0; i < cookiesFromBrowser.length(); i++) {
JSONObject cookie = cookiesFromBrowser.getJSONObject(i);
for (var i = 0; i < cookiesFromBrowser.length(); i++) {
var cookie = cookiesFromBrowser.getJSONObject(i);
if(cookie.getString("domain").contains("cam4")) {
String domain = cookie.getString("domain");
var domain = cookie.getString("domain");
if(domain.startsWith(".")) {
domain = domain.substring(1);
}
Cookie c = createCookie(domain, cookie);
var c = createCookie(domain, cookie);
cookieJar.saveFromResponse(HttpUrl.parse(url), Collections.singletonList(c));
c = createCookie("cam4.com", cookie);
cookieJar.saveFromResponse(HttpUrl.parse(Cam4.BASE_URI), Collections.singletonList(c));

View File

@ -29,17 +29,17 @@ public class Cam4FollowedTab extends ThumbOverviewTab implements FollowedTab {
}
private void addOnlineOfflineSelector() {
ToggleGroup group = new ToggleGroup();
RadioButton online = new RadioButton("online");
var group = new ToggleGroup();
var online = new RadioButton("online");
online.setToggleGroup(group);
RadioButton offline = new RadioButton("offline");
var offline = new RadioButton("offline");
offline.setToggleGroup(group);
pagination.getChildren().add(online);
pagination.getChildren().add(offline);
HBox.setMargin(online, new Insets(5,5,5,40));
HBox.setMargin(offline, new Insets(5,5,5,5));
online.setSelected(true);
group.selectedToggleProperty().addListener((e) -> {
group.selectedToggleProperty().addListener(e -> {
((Cam4FollowedUpdateService)updateService).setShowOnline(online.isSelected());
queue.clear();
updateService.restart();
@ -66,10 +66,8 @@ public class Cam4FollowedTab extends ThumbOverviewTab implements FollowedTab {
public void setScene(Scene scene) {
scene.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
if(this.isSelected()) {
if(event.getCode() == KeyCode.DELETE) {
follow(selectedThumbCells, false);
}
if (this.isSelected() && event.getCode() == KeyCode.DELETE) {
follow(selectedThumbCells, false);
}
});
}

View File

@ -6,7 +6,6 @@ import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.json.JSONArray;
import org.json.JSONObject;
import ctbrec.Model;
@ -17,7 +16,6 @@ import ctbrec.ui.SiteUiFactory;
import ctbrec.ui.tabs.PaginatedScheduledService;
import javafx.concurrent.Task;
import okhttp3.Request;
import okhttp3.Response;
public class Cam4FollowedUpdateService extends PaginatedScheduledService {
@ -27,7 +25,7 @@ public class Cam4FollowedUpdateService extends PaginatedScheduledService {
public Cam4FollowedUpdateService(Cam4 site) {
this.site = site;
ExecutorService executor = Executors.newSingleThreadExecutor(r -> {
Thread t = new Thread(r);
var t = new Thread(r);
t.setDaemon(true);
t.setName("ThumbOverviewTab UpdateService");
return t;
@ -40,37 +38,45 @@ public class Cam4FollowedUpdateService extends PaginatedScheduledService {
return new Task<List<Model>>() {
@Override
public List<Model> call() throws IOException {
// login first
SiteUiFactory.getUi(site).login();
List<Model> models = new ArrayList<>();
String url = site.getBaseUrl() + "/directoryCams?directoryJson=true&online=" + showOnline + "&url=true&friends=true&favorites=true&resultsPerPage=90";
Request req = new Request.Builder().url(url).build();
try (Response response = site.getHttpClient().execute(req)) {
if (response.isSuccessful()) {
String content = response.body().string();
JSONObject json = new JSONObject(content);
JSONArray users = json.getJSONArray("users");
for (int i = 0; i < users.length(); i++) {
JSONObject modelJson = users.getJSONObject(i);
String username = modelJson.optString("username");
Cam4Model model = site.createModel(username);
model.setPreview(modelJson.optString("snapshotImageLink"));
model.setOnlineStateByShowType(modelJson.optString("showType"));
model.setDescription(modelJson.optString("statusMessage"));
if (modelJson.has("hlsPreviewUrl")) {
model.setPlaylistUrl(modelJson.getString("hlsPreviewUrl"));
}
models.add(model);
}
return models;
} else {
throw new HttpException(response.code(), response.message());
}
}
return loadModelList();
}
};
}
private List<Model> loadModelList() throws IOException {
// login first
SiteUiFactory.getUi(site).login();
String url = site.getBaseUrl() + "/directoryCams?directoryJson=true&online=" + showOnline + "&url=true&friends=true&favorites=true&resultsPerPage=90";
Request req = new Request.Builder().url(url).build();
try (var response = site.getHttpClient().execute(req)) {
if (response.isSuccessful()) {
var content = response.body().string();
return parseModels(content);
} else {
throw new HttpException(response.code(), response.message());
}
}
}
private List<Model> parseModels(String content) {
List<Model> models = new ArrayList<>();
var json = new JSONObject(content);
var users = json.getJSONArray("users");
for (var i = 0; i < users.length(); i++) {
var modelJson = users.getJSONObject(i);
var username = modelJson.optString("username");
Cam4Model model = site.createModel(username);
model.setPreview(modelJson.optString("snapshotImageLink"));
model.setOnlineStateByShowType(modelJson.optString("showType"));
model.setDescription(modelJson.optString("statusMessage"));
if (modelJson.has("hlsPreviewUrl")) {
model.setPlaylistUrl(modelJson.getString("hlsPreviewUrl"));
}
models.add(model);
}
return models;
}
public void setShowOnline(boolean online) {
this.showOnline = online;
}

View File

@ -10,7 +10,7 @@ import ctbrec.ui.tabs.ThumbOverviewTab;
import javafx.scene.Scene;
import javafx.scene.control.Tab;
public class Cam4TabProvider extends TabProvider {
public class Cam4TabProvider implements TabProvider {
private Cam4 cam4;
private Recorder recorder;
@ -44,8 +44,8 @@ public class Cam4TabProvider extends TabProvider {
}
private Tab createTab(String name, String url) {
Cam4UpdateService updateService = new Cam4UpdateService(url, false, cam4);
ThumbOverviewTab tab = new ThumbOverviewTab(name, updateService, cam4);
var updateService = new Cam4UpdateService(url, false, cam4);
var tab = new ThumbOverviewTab(name, updateService, cam4);
tab.setRecorder(recorder);
return tab;
}

View File

@ -13,7 +13,6 @@ import java.util.concurrent.Executors;
import org.json.JSONObject;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -28,7 +27,6 @@ import ctbrec.ui.SiteUiFactory;
import ctbrec.ui.tabs.PaginatedScheduledService;
import javafx.concurrent.Task;
import okhttp3.Request;
import okhttp3.Response;
public class Cam4UpdateService extends PaginatedScheduledService {
@ -43,7 +41,7 @@ public class Cam4UpdateService extends PaginatedScheduledService {
this.loginRequired = loginRequired;
ExecutorService executor = Executors.newSingleThreadExecutor(r -> {
Thread t = new Thread(r);
var t = new Thread(r);
t.setDaemon(true);
t.setName("ThumbOverviewTab UpdateService");
return t;
@ -64,35 +62,14 @@ public class Cam4UpdateService extends PaginatedScheduledService {
if (loginRequired) {
SiteUiFactory.getUi(site).login();
}
Request request = new Request.Builder()
var request = new Request.Builder()
.url(pageUrl)
.header(ACCEPT_LANGUAGE, Locale.ENGLISH.getLanguage())
.header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent)
.build();
try (Response response = site.getHttpClient().execute(request)) {
try (var response = site.getHttpClient().execute(request)) {
if (response.isSuccessful()) {
JSONObject json = new JSONObject(response.body().string());
String html = json.getString("html");
Elements profilesBoxes = HtmlParser.getTags(html, "div[class~=profileDataBox]");
List<Model> models = new ArrayList<>(profilesBoxes.size());
for (Element profileBox : profilesBoxes) {
String boxHtml = profileBox.html();
Element profileLink = HtmlParser.getTag(boxHtml, "a.profile-preview");
String path = profileLink.attr("href");
String slug = path.substring(1);
Cam4Model model = site.createModel(slug);
String playlistUrl = profileLink.attr("data-hls-preview-url");
model.setDisplayName(HtmlParser.getText(boxHtml, "div.profileBoxTitle a").trim());
model.setPlaylistUrl(playlistUrl);
model.setPreview("https://snapshots.xcdnpro.com/thumbnails/" + model.getName() + "?s=" + System.currentTimeMillis());
model.setDescription(parseDesription(boxHtml));
model.setOnlineState(ONLINE);
if (boxHtml.contains("In private show")) {
model.setOnlineState(PRIVATE);
}
models.add(model);
}
return models;
return parseModels(response.body().string());
} else {
throw new HttpException(response.code(), response.message());
}
@ -100,17 +77,43 @@ public class Cam4UpdateService extends PaginatedScheduledService {
}
}
private String parseDesription(String boxHtml) {
try {
return HtmlParser.getText(boxHtml, "div[class~=statusMsg2]");
} catch(Exception e) {
LOG.trace("Couldn't parse description for room");
}
return "";
}
};
}
private List<Model> parseModels(String body) {
var json = new JSONObject(body);
var html = json.getString("html");
var profilesBoxes = HtmlParser.getTags(html, "div[class~=profileDataBox]");
List<Model> models = new ArrayList<>(profilesBoxes.size());
for (Element profileBox : profilesBoxes) {
String boxHtml = profileBox.html();
Element profileLink = HtmlParser.getTag(boxHtml, "a.profile-preview");
String path = profileLink.attr("href");
var slug = path.substring(1);
Cam4Model model = site.createModel(slug);
String playlistUrl = profileLink.attr("data-hls-preview-url");
model.setDisplayName(HtmlParser.getText(boxHtml, "div.profileBoxTitle a").trim());
model.setPlaylistUrl(playlistUrl);
model.setPreview("https://snapshots.xcdnpro.com/thumbnails/" + model.getName() + "?s=" + System.currentTimeMillis());
model.setDescription(parseDesription(boxHtml));
model.setOnlineState(ONLINE);
if (boxHtml.contains("In private show")) {
model.setOnlineState(PRIVATE);
}
models.add(model);
}
return models;
}
private String parseDesription(String boxHtml) {
try {
return HtmlParser.getText(boxHtml, "div[class~=statusMsg2]");
} catch(Exception e) {
LOG.trace("Couldn't parse description for room");
}
return "";
}
public void setUrl(String url) {
this.url = url;
}

View File

@ -1,7 +1,6 @@
package ctbrec.ui.sites.camsoda;
import ctbrec.Config;
import ctbrec.Settings;
import ctbrec.sites.camsoda.Camsoda;
import ctbrec.ui.DesktopIntegration;
import ctbrec.ui.settings.SettingsTab;
@ -25,15 +24,15 @@ public class CamsodaConfigUI extends AbstractConfigUI {
@Override
public Parent createConfigPanel() {
GridPane layout = SettingsTab.createGridLayout();
Settings settings = Config.getInstance().getSettings();
var layout = SettingsTab.createGridLayout();
var settings = Config.getInstance().getSettings();
int row = 0;
Label l = new Label("Active");
var row = 0;
var l = new Label("Active");
layout.add(l, 0, row);
CheckBox enabled = new CheckBox();
var enabled = new CheckBox();
enabled.setSelected(!settings.disabledSites.contains(camsoda.getName()));
enabled.setOnAction((e) -> {
enabled.setOnAction(e -> {
if(enabled.isSelected()) {
settings.disabledSites.remove(camsoda.getName());
} else {
@ -45,7 +44,7 @@ public class CamsodaConfigUI extends AbstractConfigUI {
layout.add(enabled, 1, row++);
layout.add(new Label("CamSoda User"), 0, row);
TextField username = new TextField(Config.getInstance().getSettings().camsodaUsername);
var username = new TextField(Config.getInstance().getSettings().camsodaUsername);
username.textProperty().addListener((ob, o, n) -> {
if(!n.equals(Config.getInstance().getSettings().camsodaUsername)) {
Config.getInstance().getSettings().camsodaUsername = username.getText();
@ -59,7 +58,7 @@ public class CamsodaConfigUI extends AbstractConfigUI {
layout.add(username, 1, row++);
layout.add(new Label("CamSoda Password"), 0, row);
PasswordField password = new PasswordField();
var password = new PasswordField();
password.setText(Config.getInstance().getSettings().camsodaPassword);
password.textProperty().addListener((ob, o, n) -> {
if(!n.equals(Config.getInstance().getSettings().camsodaPassword)) {
@ -73,9 +72,9 @@ public class CamsodaConfigUI extends AbstractConfigUI {
GridPane.setColumnSpan(password, 2);
layout.add(password, 1, row++);
Button createAccount = new Button("Create new Account");
createAccount.setOnAction((e) -> DesktopIntegration.open(camsoda.getAffiliateLink()));
layout.add(createAccount, 1, row++);
var createAccount = new Button("Create new Account");
createAccount.setOnAction(e -> DesktopIntegration.open(camsoda.getAffiliateLink()));
layout.add(createAccount, 1, row);
GridPane.setColumnSpan(createAccount, 2);
GridPane.setMargin(username, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
GridPane.setMargin(password, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));

View File

@ -34,10 +34,10 @@ public class CamsodaFollowedTab extends ThumbOverviewTab implements FollowedTab
}
private void addOnlineOfflineSelector() {
ToggleGroup group = new ToggleGroup();
RadioButton online = new RadioButton("online");
var group = new ToggleGroup();
var online = new RadioButton("online");
online.setToggleGroup(group);
RadioButton offline = new RadioButton("offline");
var offline = new RadioButton("offline");
offline.setToggleGroup(group);
pagination.getChildren().add(online);
pagination.getChildren().add(offline);
@ -59,7 +59,7 @@ public class CamsodaFollowedTab extends ThumbOverviewTab implements FollowedTab
@Override
protected void onFail(WorkerStateEvent event) {
String msg = "";
var msg = "";
if (event.getSource().getException() != null) {
msg = ": " + event.getSource().getException().getMessage();
}
@ -75,10 +75,8 @@ public class CamsodaFollowedTab extends ThumbOverviewTab implements FollowedTab
public void setScene(Scene scene) {
scene.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
if (this.isSelected()) {
if (event.getCode() == KeyCode.DELETE) {
follow(selectedThumbCells, false);
}
if (this.isSelected() && event.getCode() == KeyCode.DELETE) {
follow(selectedThumbCells, false);
}
});
}

View File

@ -8,13 +8,12 @@ import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.time.temporal.TemporalAccessor;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -69,7 +68,7 @@ public class CamsodaShowsTab extends Tab implements TabSelectionListener {
showList.setPadding(new Insets(5));
showList.setHgap(5);
showList.setVgap(5);
ProgressIndicator progressIndicator = new ProgressIndicator();
var progressIndicator = new ProgressIndicator();
progressIndicator.setPrefSize(100, 100);
setContent(progressIndicator);
setClosable(false);
@ -81,41 +80,7 @@ public class CamsodaShowsTab extends Tab implements TabSelectionListener {
Task<List<ShowBox>> task = new Task<List<ShowBox>>() {
@Override
protected List<ShowBox> call() throws Exception {
String url = camsoda.getBaseUrl() + "/api/v1/user/model_shows";
Request req = new Request.Builder().url(url).build();
try(Response response = camsoda.getHttpClient().execute(req)) {
if (response.isSuccessful()) {
JSONObject json = new JSONObject(response.body().string());
if (json.optInt("success") == 1) {
List<ShowBox> boxes = new ArrayList<>();
JSONArray results = json.getJSONArray("results");
for (int i = 0; i < results.length(); i++) {
JSONObject result = results.getJSONObject(i);
String modelUrl = camsoda.getBaseUrl() + result.getString("url");
String name = modelUrl.substring(modelUrl.lastIndexOf('/') + 1);
Model model = camsoda.createModel(name);
ZonedDateTime startTime = parseUtcTime(result.getString("start"));
ZonedDateTime endTime = parseUtcTime(result.getString("end"));
boxes.add(new ShowBox(model, startTime, endTime));
}
return boxes;
} else {
LOG.error("Couldn't load upcoming camsoda shows. Unexpected response: {}", json);
showErrorDialog("Oh no!", "Couldn't load upcoming CamSoda shows", "Got an unexpected response from server");
}
} else {
showErrorDialog("Oh no!", "Couldn't load upcoming CamSoda shows", "Got an unexpected response from server");
LOG.error("Couldn't load upcoming camsoda shows: {} {}", response.code(), response.message());
}
}
return Collections.emptyList();
}
private ZonedDateTime parseUtcTime(String string) {
DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
TemporalAccessor ta = formatter.parse(string.replace(" UTC", ""));
Instant instant = Instant.from(ta);
return ZonedDateTime.ofInstant(instant, ZoneId.systemDefault());
return loadShows();
}
@Override
@ -125,11 +90,14 @@ public class CamsodaShowsTab extends Tab implements TabSelectionListener {
try {
List<ShowBox> boxes = get();
showList.getChildren().clear();
int index = 0;
var index = 0;
for (ShowBox showBox : boxes) {
showList.add(showBox, index % 2, index++ / 2);
GridPane.setMargin(showBox, new Insets(20, 20, 0, 20));
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
LOG.error("Couldn't load upcoming camsoda shows", e);
} catch (Exception e) {
LOG.error("Couldn't load upcoming camsoda shows", e);
}
@ -140,6 +108,44 @@ public class CamsodaShowsTab extends Tab implements TabSelectionListener {
GlobalThreadPool.submit(task);
}
private List<ShowBox> loadShows() throws IOException {
String url = camsoda.getBaseUrl() + "/api/v1/user/model_shows";
Request req = new Request.Builder().url(url).build();
try(var response = camsoda.getHttpClient().execute(req)) {
if (response.isSuccessful()) {
var json = new JSONObject(response.body().string());
if (json.optInt("success") == 1) {
List<ShowBox> boxes = new ArrayList<>();
var results = json.getJSONArray("results");
for (var i = 0; i < results.length(); i++) {
var result = results.getJSONObject(i);
var modelUrl = camsoda.getBaseUrl() + result.getString("url");
var name = modelUrl.substring(modelUrl.lastIndexOf('/') + 1);
var model = camsoda.createModel(name);
ZonedDateTime startTime = parseUtcTime(result.getString("start"));
ZonedDateTime endTime = parseUtcTime(result.getString("end"));
boxes.add(new ShowBox(model, startTime, endTime));
}
return boxes;
} else {
LOG.error("Couldn't load upcoming camsoda shows. Unexpected response: {}", json);
showErrorDialog("Oh no!", "Couldn't load upcoming CamSoda shows", "Got an unexpected response from server");
}
} else {
showErrorDialog("Oh no!", "Couldn't load upcoming CamSoda shows", "Got an unexpected response from server");
LOG.error("Couldn't load upcoming camsoda shows: {} {}", response.code(), response.message());
}
}
return Collections.emptyList();
}
private ZonedDateTime parseUtcTime(String string) {
var formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
var ta = formatter.parse(string.replace(" UTC", ""));
var instant = Instant.from(ta);
return ZonedDateTime.ofInstant(instant, ZoneId.systemDefault());
}
@Override
public void deselected() {
// nothing to do
@ -165,31 +171,31 @@ public class CamsodaShowsTab extends Tab implements TabSelectionListener {
setPrefHeight(268);
setContent(root);
ImageView thumb = new ImageView();
var thumb = new ImageView();
thumb.setPreserveRatio(true);
thumb.setFitHeight(thumbSize);
loadImage(model, thumb);
root.setLeft(new ProgressIndicator());
BorderPane.setMargin(thumb, new Insets(10, 30, 10, 10));
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM, FormatStyle.MEDIUM);
GridPane grid = new GridPane();
var formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM, FormatStyle.MEDIUM);
var grid = new GridPane();
grid.add(createLabel("Start", true), 0, 0);
grid.add(createLabel(formatter.format(startTime), false), 1, 0);
grid.add(createLabel("End", true), 0, 1);
grid.add(createLabel(formatter.format(endTime), false), 1, 1);
Button record = new Button("Record Model");
record.setTooltip(new Tooltip(record.getText()));
record.setOnAction(evt -> record(model));
grid.add(record, 1, 2);
GridPane.setMargin(record, new Insets(10));
Button follow = new Button("Follow");
var recordButton = new Button("Record Model");
recordButton.setTooltip(new Tooltip(recordButton.getText()));
recordButton.setOnAction(evt -> recordModel(model));
grid.add(recordButton, 1, 2);
GridPane.setMargin(recordButton, new Insets(10));
var follow = new Button("Follow");
follow.setTooltip(new Tooltip(follow.getText()));
follow.setOnAction(evt -> follow(model));
grid.add(follow, 1, 3);
GridPane.setMargin(follow, new Insets(10));
Button openInBrowser = new Button("Open in Browser");
var openInBrowser = new Button("Open in Browser");
openInBrowser.setTooltip(new Tooltip(openInBrowser.getText()));
openInBrowser.setOnAction(evt -> DesktopIntegration.open(model.getUrl()));
grid.add(openInBrowser, 1, 4);
@ -197,7 +203,7 @@ public class CamsodaShowsTab extends Tab implements TabSelectionListener {
root.setCenter(grid);
loadImage(model, thumb);
record.minWidthProperty().bind(openInBrowser.widthProperty());
recordButton.minWidthProperty().bind(openInBrowser.widthProperty());
follow.minWidthProperty().bind(openInBrowser.widthProperty());
}
@ -216,7 +222,7 @@ public class CamsodaShowsTab extends Tab implements TabSelectionListener {
});
}
private void record(Model model) {
private void recordModel(Model model) {
setCursor(Cursor.WAIT);
GlobalThreadPool.submit(() -> {
try {
@ -233,47 +239,56 @@ public class CamsodaShowsTab extends Tab implements TabSelectionListener {
GlobalThreadPool.submit(() -> {
try {
String url = camsoda.getBaseUrl() + "/api/v1/user/" + model.getName();
Request detailRequest = new Request.Builder().url(url).build();
Response resp = camsoda.getHttpClient().execute(detailRequest);
if (resp.isSuccessful()) {
JSONObject json = new JSONObject(resp.body().string());
if (json.optBoolean("status") && json.has("user")) {
JSONObject user = json.getJSONObject("user");
if (user.has("settings")) {
JSONObject settings = user.getJSONObject("settings");
String imageUrl;
if(Objects.equals(System.getenv("CTBREC_DEV"), "1")) {
imageUrl = getClass().getResource("/image_not_found.png").toString();
} else {
if (settings.has("offline_picture")) {
imageUrl = settings.getString("offline_picture");
} else {
imageUrl = "https:" + user.getString("thumb");
}
}
Platform.runLater(() -> {
Image img = new Image(imageUrl, 1000, thumbSize, true, true, true);
img.progressProperty().addListener((ChangeListener<Number>) (observable, oldValue, newValue) -> {
if (newValue.doubleValue() == 1.0) {
thumb.setImage(img);
root.setLeft(thumb);
}
});
});
}
var detailRequest = new Request.Builder().url(url).build();
try (Response resp = camsoda.getHttpClient().execute(detailRequest)) {
if (resp.isSuccessful()) {
parseImageUrl(resp.body().string()).ifPresent(imageUrl -> updateImageView(thumb, imageUrl));
}
}
resp.close();
} catch (Exception e) {
LOG.error("Couldn't load model details", e);
}
});
}
private void updateImageView(ImageView view, String imageUrl) {
Platform.runLater(() -> {
var img = new Image(imageUrl, 1000, thumbSize, true, true, true);
img.progressProperty().addListener((ChangeListener<Number>) (observable, oldValue, newValue) -> {
if (newValue.doubleValue() == 1.0) {
view.setImage(img);
root.setLeft(view);
}
});
});
}
private Optional<String> parseImageUrl(String body) {
var json = new JSONObject(body);
if (json.optBoolean("status") && json.has("user")) {
var user = json.getJSONObject("user");
if (user.has("settings")) {
var settings = user.getJSONObject("settings");
String imageUrl;
if (Objects.equals(System.getenv("CTBREC_DEV"), "1")) {
imageUrl = getClass().getResource("/image_not_found.png").toString();
} else {
if (settings.has("offline_picture")) {
imageUrl = settings.getString("offline_picture");
} else {
imageUrl = "https:" + user.getString("thumb");
}
}
return Optional.of(imageUrl);
}
}
return Optional.empty();
}
private Node createLabel(String string, boolean bold) {
Label label = new Label(string);
var label = new Label(string);
label.setPadding(new Insets(10));
Font def = Font.getDefault();
var def = Font.getDefault();
label.setFont(Font.font(def.getFamily(), bold ? FontWeight.BOLD : FontWeight.NORMAL, 16));
return label;
}

View File

@ -34,58 +34,4 @@ public class CamsodaSiteUi extends AbstractSiteUi {
boolean automaticLogin = camsoda.login();
return automaticLogin;
}
// @SuppressWarnings("unused")
// private boolean loginWithDialog() throws IOException {
// BlockingQueue<Boolean> queue = new LinkedBlockingQueue<>();
//
// Runnable showDialog = () -> {
// // login with external browser
// CamsodaLoginDialog loginDialog = new CamsodaLoginDialog();
//
// // transfer cookies from WebView to OkHttp cookie jar
// transferCookies(loginDialog);
//
// try {
// queue.put(true);
// } catch (InterruptedException e) {
// LOG.error("Error while signaling termination", e);
// }
// };
//
// if(Platform.isFxApplicationThread()) {
// showDialog.run();
// } else {
// Platform.runLater(showDialog);
// try {
// queue.take();
// } catch (InterruptedException e) {
// LOG.error("Error while waiting for login dialog to close", e);
// throw new IOException(e);
// }
// }
//
// CamsodaHttpClient httpClient = (CamsodaHttpClient)camsoda.getHttpClient();
// boolean loggedIn = httpClient.checkLoginSuccess();
// return loggedIn;
// }
//
// private void transferCookies(CamsodaLoginDialog loginDialog) {
// HttpUrl redirectedUrl = HttpUrl.parse(loginDialog.getUrl());
// List<Cookie> cookies = new ArrayList<>();
// for (HttpCookie webViewCookie : loginDialog.getCookies()) {
// Cookie cookie = Cookie.parse(redirectedUrl, webViewCookie.toString());
// cookies.add(cookie);
// }
// camsoda.getHttpClient().getCookieJar().saveFromResponse(redirectedUrl, cookies);
//
// HttpUrl origUrl = HttpUrl.parse(Camsoda.BASE_URI);
// cookies = new ArrayList<>();
// for (HttpCookie webViewCookie : loginDialog.getCookies()) {
// Cookie cookie = Cookie.parse(origUrl, webViewCookie.toString());
// cookies.add(cookie);
// }
// camsoda.getHttpClient().getCookieJar().saveFromResponse(origUrl, cookies);
// }
}

View File

@ -15,7 +15,7 @@ import ctbrec.ui.tabs.ThumbOverviewTab;
import javafx.scene.Scene;
import javafx.scene.control.Tab;
public class CamsodaTabProvider extends TabProvider {
public class CamsodaTabProvider implements TabProvider {
private static final String API_URL = BASE_URI + "/api/v1/browse/online";
private Camsoda camsoda;
@ -37,7 +37,6 @@ public class CamsodaTabProvider extends TabProvider {
tabs.add(createTab("Male", API_URL, m -> Objects.equals("m", m.getGender())));
tabs.add(createTab("Couples", API_URL, m -> Objects.equals("c", m.getGender())));
tabs.add(createTab("Trans", API_URL, m -> Objects.equals("t", m.getGender())));
//tabs.add(createTab("#petite", BASE_URI + "/api/v1/browse/tag-petite", m -> true));
followedTab.setRecorder(recorder);
followedTab.setScene(scene);
tabs.add(followedTab);
@ -51,8 +50,8 @@ public class CamsodaTabProvider extends TabProvider {
}
private Tab createTab(String title, String url, Predicate<CamsodaModel> filter) {
CamsodaUpdateService updateService = new CamsodaUpdateService(url, false, camsoda, filter);
ThumbOverviewTab tab = new ThumbOverviewTab(title, updateService, camsoda);
var updateService = new CamsodaUpdateService(url, false, camsoda, filter);
var tab = new ThumbOverviewTab(title, updateService, camsoda);
tab.setRecorder(recorder);
return tab;
}

View File

@ -25,7 +25,6 @@ import ctbrec.ui.SiteUiFactory;
import ctbrec.ui.tabs.PaginatedScheduledService;
import javafx.concurrent.Task;
import okhttp3.Request;
import okhttp3.Response;
public class CamsodaUpdateService extends PaginatedScheduledService {
@ -53,7 +52,7 @@ public class CamsodaUpdateService extends PaginatedScheduledService {
return loadOnlineModels().stream()
.sorted((m1,m2) -> (int)(m2.getSortOrder() - m1.getSortOrder()))
.filter(filter)
.skip( (page-1) * modelsPerPage)
.skip( (page-1) * (long)modelsPerPage)
.limit(modelsPerPage)
.collect(Collectors.toList());
}
@ -61,71 +60,17 @@ public class CamsodaUpdateService extends PaginatedScheduledService {
}
protected List<CamsodaModel> loadOnlineModels() throws IOException {
List<CamsodaModel> models = new ArrayList<>();
if(loginRequired && StringUtil.isBlank(ctbrec.Config.getInstance().getSettings().camsodaUsername)) {
if (loginRequired && StringUtil.isBlank(ctbrec.Config.getInstance().getSettings().camsodaUsername)) {
return Collections.emptyList();
} else {
LOG.debug("Fetching page {}", url);
if(loginRequired) {
if (loginRequired) {
SiteUiFactory.getUi(camsoda).login();
}
Request request = new Request.Builder().url(url).build();
try (Response response = camsoda.getHttpClient().execute(request)) {
var request = new Request.Builder().url(url).build();
try (var response = camsoda.getHttpClient().execute(request)) {
if (response.isSuccessful()) {
String body = response.body().string();
JSONObject json = new JSONObject(body);
JSONArray template = json.getJSONArray("template");
JSONArray results = json.getJSONArray("results");
for (int i = 0; i < results.length(); i++) {
JSONObject result = results.getJSONObject(i);
Object templateObject = result.get("tpl");
CamsodaModel model;
try {
if (templateObject instanceof JSONObject) {
JSONObject tpl = (JSONObject) templateObject;
String name = tpl.getString(Integer.toString(getTemplateIndex(template, "username")));
model = (CamsodaModel) camsoda.createModel(name);
model.setDescription(tpl.getString(Integer.toString(getTemplateIndex(template, "subject_html"))));
model.setSortOrder(tpl.getFloat(Integer.toString(getTemplateIndex(template, "sort_value"))));
model.setNew(result.optBoolean("new"));
model.setGender(tpl.getString(Integer.toString(getTemplateIndex(template, "gender"))));
String preview = "https:" + tpl.getString(Integer.toString(getTemplateIndex(template, "thumb")));
model.setPreview(preview);
String displayName = tpl.getString(Integer.toString(getTemplateIndex(template, "display_name")));
model.setDisplayName(displayName.replaceAll("[^a-zA-Z0-9]", ""));
if (model.getDisplayName().isBlank()) {
model.setDisplayName(name);
}
model.setOnlineState(tpl.getString(Integer.toString(getTemplateIndex(template, "stream_name"))).isEmpty() ? OFFLINE : ONLINE);
try {
String statusIndex = Integer.toString(getTemplateIndex(template, "status"));
if (tpl.has(statusIndex)) {
model.setOnlineStateByStatus(tpl.getString(statusIndex));
}
} catch (NoSuchElementException e) {
}
models.add(model);
} else if (templateObject instanceof JSONArray) {
JSONArray tpl = (JSONArray) templateObject;
String name = tpl.getString(getTemplateIndex(template, "username"));
model = (CamsodaModel) camsoda.createModel(name);
model.setSortOrder(tpl.getFloat(getTemplateIndex(template, "sort_value")));
model.setDescription(tpl.getString(getTemplateIndex(template, "subject_html")));
String preview = "https:" + tpl.getString(getTemplateIndex(template, "thumb"));
model.setPreview(preview);
model.setOnlineStateByStatus(tpl.getString(getTemplateIndex(template, "status")));
String displayName = tpl.getString(getTemplateIndex(template, "display_name"));
model.setDisplayName(displayName.replaceAll("[^a-zA-Z0-9]", ""));
if (model.getDisplayName().isBlank()) {
model.setDisplayName(name);
}
models.add(model);
}
} catch (Exception e) {
LOG.warn("Couldn't parse one of the models: {}", result, e);
}
}
return models;
return parseModels(response.body().string());
} else {
throw new HttpException(response.code(), response.message());
}
@ -133,10 +78,79 @@ public class CamsodaUpdateService extends PaginatedScheduledService {
}
}
private List<CamsodaModel> parseModels(String body) {
List<CamsodaModel> models = new ArrayList<>();
var json = new JSONObject(body);
var template = json.getJSONArray("template");
var results = json.getJSONArray("results");
for (var i = 0; i < results.length(); i++) {
var result = results.getJSONObject(i);
var templateObject = result.get("tpl");
try {
if (templateObject instanceof JSONObject) {
parseModelFromObject(result, templateObject, template, models);
} else if (templateObject instanceof JSONArray) {
parseModelFromArray(templateObject, template, models);
}
} catch (Exception e) {
LOG.warn("Couldn't parse one of the models: {}", result, e);
}
}
return models;
}
private void parseModelFromArray(Object templateObject, JSONArray template, List<CamsodaModel> models) {
var tpl = (JSONArray) templateObject;
var name = tpl.getString(getTemplateIndex(template, "username"));
CamsodaModel model = (CamsodaModel) camsoda.createModel(name);
model.setSortOrder(tpl.getFloat(getTemplateIndex(template, "sort_value")));
model.setDescription(tpl.getString(getTemplateIndex(template, "subject_html")));
var preview = "https:" + tpl.getString(getTemplateIndex(template, "thumb"));
model.setPreview(preview);
model.setOnlineStateByStatus(tpl.getString(getTemplateIndex(template, "status")));
var displayName = tpl.getString(getTemplateIndex(template, "display_name"));
model.setDisplayName(displayName.replaceAll("[^a-zA-Z0-9]", ""));
if (model.getDisplayName().isBlank()) {
model.setDisplayName(name);
}
models.add(model);
}
private void parseModelFromObject(JSONObject result, Object templateObject, JSONArray template, List<CamsodaModel> models) {
var tpl = (JSONObject) templateObject;
var name = tpl.getString(Integer.toString(getTemplateIndex(template, "username")));
CamsodaModel model = (CamsodaModel) camsoda.createModel(name);
model.setDescription(tpl.getString(Integer.toString(getTemplateIndex(template, "subject_html"))));
model.setSortOrder(tpl.getFloat(Integer.toString(getTemplateIndex(template, "sort_value"))));
model.setNew(result.optBoolean("new"));
model.setGender(tpl.getString(Integer.toString(getTemplateIndex(template, "gender"))));
var preview = "https:" + tpl.getString(Integer.toString(getTemplateIndex(template, "thumb")));
model.setPreview(preview);
var displayName = tpl.getString(Integer.toString(getTemplateIndex(template, "display_name")));
model.setDisplayName(displayName.replaceAll("[^a-zA-Z0-9]", ""));
if (model.getDisplayName().isBlank()) {
model.setDisplayName(name);
}
model.setOnlineState(tpl.getString(Integer.toString(getTemplateIndex(template, "stream_name"))).isEmpty() ? OFFLINE : ONLINE);
parseStatus(template, tpl, model);
models.add(model);
}
private void parseStatus(JSONArray template, JSONObject tpl, CamsodaModel model) {
try {
var statusIndex = Integer.toString(getTemplateIndex(template, "status"));
if (tpl.has(statusIndex)) {
model.setOnlineStateByStatus(tpl.getString(statusIndex));
}
} catch (NoSuchElementException e) {
// that's ok
}
}
private int getTemplateIndex(JSONArray template, String string) {
for (int i = 0; i < template.length(); i++) {
String s = template.getString(i);
if(Objects.equals(s, string)) {
for (var i = 0; i < template.length(); i++) {
var s = template.getString(i);
if (Objects.equals(s, string)) {
return i;
}
}

View File

@ -1,7 +1,6 @@
package ctbrec.ui.sites.chaturbate;
import ctbrec.Config;
import ctbrec.Settings;
import ctbrec.sites.chaturbate.Chaturbate;
import ctbrec.ui.DesktopIntegration;
import ctbrec.ui.settings.SettingsTab;
@ -25,15 +24,15 @@ public class ChaturbateConfigUi extends AbstractConfigUI {
@Override
public Parent createConfigPanel() {
Settings settings = Config.getInstance().getSettings();
var settings = Config.getInstance().getSettings();
GridPane layout = SettingsTab.createGridLayout();
int row = 0;
Label l = new Label("Active");
var row = 0;
var l = new Label("Active");
layout.add(l, 0, row);
CheckBox enabled = new CheckBox();
var enabled = new CheckBox();
enabled.setSelected(!settings.disabledSites.contains(chaturbate.getName()));
enabled.setOnAction((e) -> {
enabled.setOnAction(e -> {
if(enabled.isSelected()) {
settings.disabledSites.remove(chaturbate.getName());
} else {
@ -45,7 +44,7 @@ public class ChaturbateConfigUi extends AbstractConfigUI {
layout.add(enabled, 1, row++);
layout.add(new Label("Chaturbate User"), 0, row);
TextField username = new TextField(Config.getInstance().getSettings().chaturbateUsername);
var username = new TextField(Config.getInstance().getSettings().chaturbateUsername);
username.textProperty().addListener((ob, o, n) -> {
if(!n.equals(Config.getInstance().getSettings().chaturbateUsername)) {
Config.getInstance().getSettings().chaturbateUsername = n;
@ -59,7 +58,7 @@ public class ChaturbateConfigUi extends AbstractConfigUI {
layout.add(username, 1, row++);
layout.add(new Label("Chaturbate Password"), 0, row);
PasswordField password = new PasswordField();
var password = new PasswordField();
password.setText(Config.getInstance().getSettings().chaturbatePassword);
password.textProperty().addListener((ob, o, n) -> {
if(!n.equals(Config.getInstance().getSettings().chaturbatePassword)) {
@ -74,7 +73,7 @@ public class ChaturbateConfigUi extends AbstractConfigUI {
layout.add(password, 1, row++);
layout.add(new Label("Chaturbate Base URL"), 0, row);
TextField baseUrl = new TextField();
var baseUrl = new TextField();
baseUrl.setText(Config.getInstance().getSettings().chaturbateBaseUrl);
baseUrl.textProperty().addListener((ob, o, n) -> {
Config.getInstance().getSettings().chaturbateBaseUrl = baseUrl.getText();
@ -85,9 +84,9 @@ public class ChaturbateConfigUi extends AbstractConfigUI {
GridPane.setColumnSpan(baseUrl, 2);
layout.add(baseUrl, 1, row++);
Button createAccount = new Button("Create new Account");
createAccount.setOnAction((e) -> DesktopIntegration.open(Chaturbate.REGISTRATION_LINK));
layout.add(createAccount, 1, row++);
var createAccount = new Button("Create new Account");
createAccount.setOnAction(e -> DesktopIntegration.open(Chaturbate.REGISTRATION_LINK));
layout.add(createAccount, 1, row);
GridPane.setColumnSpan(createAccount, 2);
GridPane.setMargin(username, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
GridPane.setMargin(password, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));

View File

@ -34,17 +34,17 @@ public class ChaturbateFollowedTab extends ThumbOverviewTab implements FollowedT
}
private void addOnlineOfflineSelector() {
ToggleGroup group = new ToggleGroup();
RadioButton online = new RadioButton("online");
var group = new ToggleGroup();
var online = new RadioButton("online");
online.setToggleGroup(group);
RadioButton offline = new RadioButton("offline");
var offline = new RadioButton("offline");
offline.setToggleGroup(group);
pagination.getChildren().add(online);
pagination.getChildren().add(offline);
HBox.setMargin(online, new Insets(5,5,5,40));
HBox.setMargin(offline, new Insets(5,5,5,5));
online.setSelected(true);
group.selectedToggleProperty().addListener((e) -> {
group.selectedToggleProperty().addListener(e -> {
if(online.isSelected()) {
((ChaturbateUpdateService)updateService).setUrl(onlineUrl);
} else {
@ -75,10 +75,8 @@ public class ChaturbateFollowedTab extends ThumbOverviewTab implements FollowedT
public void setScene(Scene scene) {
scene.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
if(this.isSelected()) {
if(event.getCode() == KeyCode.DELETE) {
follow(selectedThumbCells, false);
}
if (this.isSelected() && event.getCode() == KeyCode.DELETE) {
follow(selectedThumbCells, false);
}
});
}

View File

@ -10,7 +10,7 @@ import ctbrec.ui.tabs.ThumbOverviewTab;
import javafx.scene.Scene;
import javafx.scene.control.Tab;
public class ChaturbateTabProvider extends TabProvider {
public class ChaturbateTabProvider implements TabProvider {
private Chaturbate chaturbate;
private Recorder recorder;
@ -44,8 +44,8 @@ public class ChaturbateTabProvider extends TabProvider {
}
private Tab createTab(String title, String url) {
ChaturbateUpdateService updateService = new ChaturbateUpdateService(url, false, chaturbate);
ThumbOverviewTab tab = new ThumbOverviewTab(title, updateService, chaturbate);
var updateService = new ChaturbateUpdateService(url, false, chaturbate);
var tab = new ThumbOverviewTab(title, updateService, chaturbate);
tab.setRecorder(recorder);
tab.setImageAspectRatio(9.0 / 16.0);
return tab;

View File

@ -16,7 +16,6 @@ import ctbrec.ui.SiteUiFactory;
import ctbrec.ui.tabs.PaginatedScheduledService;
import javafx.concurrent.Task;
import okhttp3.Request;
import okhttp3.Response;
public class ChaturbateUpdateService extends PaginatedScheduledService {
@ -31,7 +30,7 @@ public class ChaturbateUpdateService extends PaginatedScheduledService {
this.chaturbate = chaturbate;
ExecutorService executor = Executors.newSingleThreadExecutor(r -> {
Thread t = new Thread(r);
var t = new Thread(r);
t.setDaemon(true);
t.setName("ThumbOverviewTab UpdateService");
return t;
@ -44,7 +43,7 @@ public class ChaturbateUpdateService extends PaginatedScheduledService {
return new Task<List<Model>>() {
@Override
public List<Model> call() throws IOException {
if(loginRequired && !chaturbate.credentialsAvailable()) {
if (loginRequired && !chaturbate.credentialsAvailable()) {
return Collections.emptyList();
} else {
String pageUrl = ChaturbateUpdateService.this.url + "?page="+page+"&keywords=&_=" + System.currentTimeMillis();
@ -52,16 +51,15 @@ public class ChaturbateUpdateService extends PaginatedScheduledService {
if(loginRequired) {
SiteUiFactory.getUi(chaturbate).login();
}
Request request = new Request.Builder().url(pageUrl).build();
Response response = chaturbate.getHttpClient().execute(request);
if (response.isSuccessful()) {
List<Model> models = ChaturbateModelParser.parseModels(chaturbate, response.body().string());
response.close();
return models;
} else {
int code = response.code();
response.close();
throw new IOException("HTTP status " + code);
var request = new Request.Builder().url(pageUrl).build();
try (var response = chaturbate.getHttpClient().execute(request)) {
if (response.isSuccessful()) {
List<Model> models = ChaturbateModelParser.parseModels(chaturbate, response.body().string());
return models;
} else {
int code = response.code();
throw new IOException("HTTP status " + code);
}
}
}
}

View File

@ -14,25 +14,19 @@ public class Fc2FollowedTab extends ThumbOverviewTab implements FollowedTab {
super("Followed", new Fc2FollowedUpdateService(fc2live), fc2live);
}
@Override
protected void createGui() {
super.createGui();
//addOnlineOfflineSelector();
}
@SuppressWarnings("unused")
private void addOnlineOfflineSelector() {
ToggleGroup group = new ToggleGroup();
RadioButton online = new RadioButton("online");
var group = new ToggleGroup();
var online = new RadioButton("online");
online.setToggleGroup(group);
RadioButton offline = new RadioButton("offline");
var offline = new RadioButton("offline");
offline.setToggleGroup(group);
pagination.getChildren().add(online);
pagination.getChildren().add(offline);
HBox.setMargin(online, new Insets(5,5,5,40));
HBox.setMargin(offline, new Insets(5,5,5,5));
online.setSelected(true);
group.selectedToggleProperty().addListener((e) -> {
group.selectedToggleProperty().addListener(e -> {
((Fc2FollowedUpdateService)updateService).setShowOnline(online.isSelected());
queue.clear();
updateService.restart();

View File

@ -6,7 +6,6 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONObject;
import ctbrec.Config;
@ -34,54 +33,58 @@ public class Fc2FollowedUpdateService extends PaginatedScheduledService {
return new Task<List<Model>>() {
@Override
public List<Model> call() throws IOException {
if(!fc2live.login()) {
throw new IOException("Login didn't work");
}
RequestBody body = new FormBody.Builder()
.add("mode", "list")
.add("page", Integer.toString(page - 1))
.build();
Request req = new Request.Builder()
.url(fc2live.getBaseUrl() + "/api/favoriteManager.php")
.header(REFERER, fc2live.getBaseUrl())
.header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent)
.header("Content-Type", "application/x-www-form-urlencoded")
.post(body)
.build();
try(Response resp = fc2live.getHttpClient().execute(req)) {
if(resp.isSuccessful()) {
List<Model> models = new ArrayList<>();
String content = resp.body().string();
JSONObject json = new JSONObject(content);
if(json.optInt("status") == 1) {
JSONArray data = json.getJSONArray("data");
for (int i = 0; i < data.length(); i++) {
JSONObject m = data.getJSONObject(i);
Fc2Model model = (Fc2Model) fc2live.createModel(m.getString("name"));
model.setId(m.getString("id"));
model.setUrl(Fc2Live.BASE_URL + '/' + model.getId());
String previewUrl = m.optString("icon");
if(previewUrl == null || previewUrl.trim().isEmpty()) {
previewUrl = "https://live-storage.fc2.com/thumb/" + model.getId() + "/thumb.jpg";
}
model.setPreview(previewUrl);
model.setDescription("");
models.add(model);
}
return models;
} else {
throw new IOException("Request was not successful: " + json.toString());
}
} else {
throw new HttpException(resp.code(), resp.message());
}
}
return loadModels();
}
};
}
public void setShowOnline(boolean online) {
//this.online = online;
private List<Model> loadModels() throws IOException {
if(!fc2live.login()) {
throw new IOException("Login didn't work");
}
RequestBody body = new FormBody.Builder()
.add("mode", "list")
.add("page", Integer.toString(page - 1))
.build();
Request req = new Request.Builder()
.url(fc2live.getBaseUrl() + "/api/favoriteManager.php")
.header(REFERER, fc2live.getBaseUrl())
.header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent)
.header("Content-Type", "application/x-www-form-urlencoded")
.post(body)
.build();
try (Response resp = fc2live.getHttpClient().execute(req)) {
if (resp.isSuccessful()) {
List<Model> models = new ArrayList<>();
var content = resp.body().string();
var json = new JSONObject(content);
if (json.optInt("status") == 1) {
var data = json.getJSONArray("data");
for (var i = 0; i < data.length(); i++) {
var m = data.getJSONObject(i);
Fc2Model model = (Fc2Model) fc2live.createModel(m.getString("name"));
model.setId(m.getString("id"));
model.setUrl(Fc2Live.BASE_URL + '/' + model.getId());
var previewUrl = m.optString("icon");
if (previewUrl == null || previewUrl.trim().isEmpty()) {
previewUrl = "https://live-storage.fc2.com/thumb/" + model.getId() + "/thumb.jpg";
}
model.setPreview(previewUrl);
model.setDescription("");
models.add(model);
}
return models;
} else {
throw new IOException("Request was not successful: " + json.toString());
}
} else {
throw new HttpException(resp.code(), resp.message());
}
}
}
public void setShowOnline(boolean yes) {
// not implemented yet
}
}

View File

@ -1,7 +1,6 @@
package ctbrec.ui.sites.fc2live;
import ctbrec.Config;
import ctbrec.Settings;
import ctbrec.sites.fc2live.Fc2Live;
import ctbrec.ui.DesktopIntegration;
import ctbrec.ui.settings.SettingsTab;
@ -25,15 +24,15 @@ public class Fc2LiveConfigUI extends AbstractConfigUI {
@Override
public Parent createConfigPanel() {
GridPane layout = SettingsTab.createGridLayout();
Settings settings = Config.getInstance().getSettings();
var layout = SettingsTab.createGridLayout();
var settings = Config.getInstance().getSettings();
int row = 0;
Label l = new Label("Active");
var row = 0;
var l = new Label("Active");
layout.add(l, 0, row);
CheckBox enabled = new CheckBox();
var enabled = new CheckBox();
enabled.setSelected(!settings.disabledSites.contains(fc2live.getName()));
enabled.setOnAction((e) -> {
enabled.setOnAction(e -> {
if(enabled.isSelected()) {
settings.disabledSites.remove(fc2live.getName());
} else {
@ -45,7 +44,7 @@ public class Fc2LiveConfigUI extends AbstractConfigUI {
layout.add(enabled, 1, row++);
layout.add(new Label("FC2Live User"), 0, row);
TextField username = new TextField(settings.fc2liveUsername);
var username = new TextField(settings.fc2liveUsername);
username.textProperty().addListener((ob, o, n) -> {
if(!n.equals(Config.getInstance().getSettings().fc2liveUsername)) {
Config.getInstance().getSettings().fc2liveUsername = username.getText();
@ -59,7 +58,7 @@ public class Fc2LiveConfigUI extends AbstractConfigUI {
layout.add(username, 1, row++);
layout.add(new Label("FC2Live Password"), 0, row);
PasswordField password = new PasswordField();
var password = new PasswordField();
password.setText(settings.fc2livePassword);
password.textProperty().addListener((ob, o, n) -> {
if(!n.equals(Config.getInstance().getSettings().fc2livePassword)) {
@ -73,9 +72,9 @@ public class Fc2LiveConfigUI extends AbstractConfigUI {
GridPane.setColumnSpan(password, 2);
layout.add(password, 1, row++);
Button createAccount = new Button("Create new Account");
createAccount.setOnAction((e) -> DesktopIntegration.open(fc2live.getAffiliateLink()));
layout.add(createAccount, 1, row++);
var createAccount = new Button("Create new Account");
createAccount.setOnAction(e -> DesktopIntegration.open(fc2live.getAffiliateLink()));
layout.add(createAccount, 1, row);
GridPane.setColumnSpan(createAccount, 2);
GridPane.setMargin(username, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
GridPane.setMargin(password, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));

View File

@ -9,7 +9,7 @@ import ctbrec.ui.tabs.ThumbOverviewTab;
import javafx.scene.Scene;
import javafx.scene.control.Tab;
public class Fc2TabProvider extends TabProvider {
public class Fc2TabProvider implements TabProvider {
private Fc2Live fc2live;
private Fc2FollowedTab followed;
@ -31,8 +31,8 @@ public class Fc2TabProvider extends TabProvider {
}
private Tab createTab(String title, String url) {
Fc2UpdateService updateService = new Fc2UpdateService(url, fc2live);
ThumbOverviewTab tab = new ThumbOverviewTab(title, updateService, fc2live);
var updateService = new Fc2UpdateService(url, fc2live);
var tab = new ThumbOverviewTab(title, updateService, fc2live);
tab.setRecorder(fc2live.getRecorder());
return tab;
}

View File

@ -8,7 +8,6 @@ import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -22,7 +21,6 @@ import ctbrec.ui.tabs.PaginatedScheduledService;
import javafx.concurrent.Task;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class Fc2UpdateService extends PaginatedScheduledService {
private static final Logger LOG = LoggerFactory.getLogger(Fc2UpdateService.class);
@ -41,7 +39,7 @@ public class Fc2UpdateService extends PaginatedScheduledService {
return new Task<List<Model>>() {
@Override
public List<Model> call() throws IOException {
RequestBody body = RequestBody.create(new byte[0]);
var body = RequestBody.create(new byte[0]);
Request req = new Request.Builder()
.url(url)
.method("POST", body)
@ -52,31 +50,31 @@ public class Fc2UpdateService extends PaginatedScheduledService {
.header(X_REQUESTED_WITH, XML_HTTP_REQUEST)
.build();
LOG.debug("Fetching page {}", url);
try(Response resp = fc2live.getHttpClient().execute(req)) {
if(resp.isSuccessful()) {
try (var resp = fc2live.getHttpClient().execute(req)) {
if (resp.isSuccessful()) {
List<Fc2Model> models = new ArrayList<>();
String msg = resp.body().string();
JSONObject json = new JSONObject(msg);
JSONArray channels = json.getJSONArray("channel");
for (int i = 0; i < channels.length(); i++) {
JSONObject channel = channels.getJSONObject(i);
var msg = resp.body().string();
var json = new JSONObject(msg);
var channels = json.getJSONArray("channel");
for (var i = 0; i < channels.length(); i++) {
var channel = channels.getJSONObject(i);
Fc2Model model = (Fc2Model) fc2live.createModel(channel.getString("name"));
model.setId(channel.getString("id"));
model.setUrl(Fc2Live.BASE_URL + '/' + model.getId());
String previewUrl = channel.getString("image");
if(previewUrl == null || previewUrl.trim().isEmpty()) {
var previewUrl = channel.getString("image");
if (previewUrl == null || previewUrl.trim().isEmpty()) {
previewUrl = getClass().getResource("/image_not_found.png").toString();
}
model.setPreview(previewUrl);
model.setDescription(channel.optString("title"));
model.setViewerCount(channel.optInt("count"));
if(channel.getInt("login") == 0) {
if (channel.getInt("login") == 0) {
models.add(model);
}
}
return models.stream()
.sorted((m1, m2) -> m2.getViewerCount() - m1.getViewerCount())
.skip( (long)(page - 1) * modelsPerPage)
.skip((long) (page - 1) * modelsPerPage)
.limit(modelsPerPage)
.collect(Collectors.toList());
} else {

View File

@ -1,7 +1,6 @@
package ctbrec.ui.sites.flirt4free;
import ctbrec.Config;
import ctbrec.Settings;
import ctbrec.sites.flirt4free.Flirt4Free;
import ctbrec.ui.DesktopIntegration;
import ctbrec.ui.settings.SettingsTab;
@ -25,15 +24,15 @@ public class Flirt4FreeConfigUI extends AbstractConfigUI {
@Override
public Parent createConfigPanel() {
GridPane layout = SettingsTab.createGridLayout();
Settings settings = Config.getInstance().getSettings();
var layout = SettingsTab.createGridLayout();
var settings = Config.getInstance().getSettings();
int row = 0;
Label l = new Label("Active");
var row = 0;
var l = new Label("Active");
layout.add(l, 0, row);
CheckBox enabled = new CheckBox();
var enabled = new CheckBox();
enabled.setSelected(!settings.disabledSites.contains(flirt4free.getName()));
enabled.setOnAction((e) -> {
enabled.setOnAction(e -> {
if(enabled.isSelected()) {
settings.disabledSites.remove(flirt4free.getName());
} else {
@ -45,7 +44,7 @@ public class Flirt4FreeConfigUI extends AbstractConfigUI {
layout.add(enabled, 1, row++);
layout.add(new Label("Flirt4Free User"), 0, row);
TextField username = new TextField(settings.flirt4freeUsername);
var username = new TextField(settings.flirt4freeUsername);
username.textProperty().addListener((ob, o, n) -> {
if(!n.equals(Config.getInstance().getSettings().flirt4freeUsername)) {
Config.getInstance().getSettings().flirt4freeUsername = username.getText();
@ -59,7 +58,7 @@ public class Flirt4FreeConfigUI extends AbstractConfigUI {
layout.add(username, 1, row++);
layout.add(new Label("Flirt4Free Password"), 0, row);
PasswordField password = new PasswordField();
var password = new PasswordField();
password.setText(settings.flirt4freePassword);
password.textProperty().addListener((ob, o, n) -> {
if(!n.equals(Config.getInstance().getSettings().flirt4freePassword)) {
@ -73,9 +72,9 @@ public class Flirt4FreeConfigUI extends AbstractConfigUI {
GridPane.setColumnSpan(password, 2);
layout.add(password, 1, row++);
Button createAccount = new Button("Create new Account");
createAccount.setOnAction((e) -> DesktopIntegration.open(flirt4free.getAffiliateLink()));
layout.add(createAccount, 1, row++);
var createAccount = new Button("Create new Account");
createAccount.setOnAction(e -> DesktopIntegration.open(flirt4free.getAffiliateLink()));
layout.add(createAccount, 1, row);
GridPane.setColumnSpan(createAccount, 2);
GridPane.setMargin(username, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
GridPane.setMargin(password, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));

View File

@ -15,10 +15,8 @@ public class Flirt4FreeFavoritesTab extends ThumbOverviewTab implements Followed
public void setScene(Scene scene) {
scene.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
if(this.isSelected()) {
if(event.getCode() == KeyCode.DELETE) {
follow(selectedThumbCells, false);
}
if (this.isSelected() && event.getCode() == KeyCode.DELETE) {
follow(selectedThumbCells, false);
}
});
}

View File

@ -21,7 +21,6 @@ import ctbrec.ui.SiteUiFactory;
import ctbrec.ui.tabs.PaginatedScheduledService;
import javafx.concurrent.Task;
import okhttp3.Request;
import okhttp3.Response;
public class Flirt4FreeFavoritesUpdateService extends PaginatedScheduledService {
private Flirt4Free flirt4free;
@ -35,45 +34,49 @@ public class Flirt4FreeFavoritesUpdateService extends PaginatedScheduledService
return new Task<List<Model>>() {
@Override
public List<Model> call() throws IOException {
List<Model> models = new ArrayList<>();
String url = flirt4free.getBaseUrl() + "/my-account/secure/favorites.php?a=models&sort=online&status=all&pg=" + page;
SiteUiFactory.getUi(flirt4free).login();
Request request = new Request.Builder()
.url(url)
.header(ACCEPT, "*/*")
.header(ACCEPT_LANGUAGE, Locale.ENGLISH.getLanguage())
.header(REFERER, flirt4free.getBaseUrl())
.header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent)
.build();
try (Response response = flirt4free.getHttpClient().execute(request)) {
if (response.isSuccessful()) {
String body = response.body().string();
Elements modelContainers = HtmlParser.getTags(body, "div.model-container");
for (Element modelContainer : modelContainers) {
String modelHtml = modelContainer.html();
Element bioLink = HtmlParser.getTag(modelHtml, "a.common-link");
bioLink.setBaseUri(flirt4free.getBaseUrl());
Flirt4FreeModel model = (Flirt4FreeModel) flirt4free.createModelFromUrl(bioLink.absUrl("href"));
Element img = HtmlParser.getTag(modelHtml, "a > img[alt]");
model.setDisplayName(img.attr("alt"));
model.setPreview(img.attr("src"));
model.setDescription("");
model.setOnline(modelHtml.contains("I'm Online"));
try {
model.setOnlineState(model.isOnline() ? Model.State.ONLINE : Model.State.OFFLINE);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (ExecutionException e) {
// ignore
}
models.add(model);
}
return models;
} else {
throw new HttpException(response.code(), response.message());
}
}
return loadModelList();
}
};
}
private List<Model> loadModelList() throws IOException {
List<Model> models = new ArrayList<>();
String url = flirt4free.getBaseUrl() + "/my-account/secure/favorites.php?a=models&sort=online&status=all&pg=" + page;
SiteUiFactory.getUi(flirt4free).login();
var request = new Request.Builder()
.url(url)
.header(ACCEPT, "*/*")
.header(ACCEPT_LANGUAGE, Locale.ENGLISH.getLanguage())
.header(REFERER, flirt4free.getBaseUrl())
.header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent)
.build();
try (var response = flirt4free.getHttpClient().execute(request)) {
if (response.isSuccessful()) {
var body = response.body().string();
Elements modelContainers = HtmlParser.getTags(body, "div.model-container");
for (Element modelContainer : modelContainers) {
String modelHtml = modelContainer.html();
Element bioLink = HtmlParser.getTag(modelHtml, "a.common-link");
bioLink.setBaseUri(flirt4free.getBaseUrl());
Flirt4FreeModel model = (Flirt4FreeModel) flirt4free.createModelFromUrl(bioLink.absUrl("href"));
Element img = HtmlParser.getTag(modelHtml, "a > img[alt]");
model.setDisplayName(img.attr("alt"));
model.setPreview(img.attr("src"));
model.setDescription("");
model.setOnline(modelHtml.contains("I'm Online"));
try {
model.setOnlineState(model.isOnline() ? Model.State.ONLINE : Model.State.OFFLINE);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (ExecutionException e) {
// ignore
}
models.add(model);
}
return models;
} else {
throw new HttpException(response.code(), response.message());
}
}
}
}

View File

@ -12,7 +12,7 @@ import javafx.scene.Scene;
import javafx.scene.control.Tab;
import javafx.util.Duration;
public class Flirt4FreeTabProvider extends TabProvider {
public class Flirt4FreeTabProvider implements TabProvider {
private Flirt4Free flirt4Free;
private ThumbOverviewTab followedTab;
@ -40,8 +40,8 @@ public class Flirt4FreeTabProvider extends TabProvider {
}
private ThumbOverviewTab createTab(String title, String url, Predicate<Flirt4FreeModel> filter) {
Flirt4FreeUpdateService s = new Flirt4FreeUpdateService(flirt4Free, url, filter);
ThumbOverviewTab tab = new ThumbOverviewTab(title, s, flirt4Free);
var s = new Flirt4FreeUpdateService(flirt4Free, url, filter);
var tab = new ThumbOverviewTab(title, s, flirt4Free);
tab.setRecorder(flirt4Free.getRecorder());
s.setPeriod(Duration.seconds(60));
return tab;

View File

@ -6,11 +6,9 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -45,11 +43,11 @@ public class Flirt4FreeUpdateService extends PaginatedScheduledService {
@Override
public List<Model> call() throws IOException {
LOG.debug("Fetching page {}", url);
Request request = new Request.Builder()
var request = new Request.Builder()
.url(url)
.header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent)
.build();
try (Response response = flirt4Free.getHttpClient().execute(request)) {
try (var response = flirt4Free.getHttpClient().execute(request)) {
if (response.isSuccessful()) {
return parseResponse(response);
} else {
@ -62,26 +60,24 @@ public class Flirt4FreeUpdateService extends PaginatedScheduledService {
private List<Model> parseResponse(Response response) throws IOException {
List<Flirt4FreeModel> models = new ArrayList<>();
String body = response.body().string();
Matcher m = Pattern.compile("window\\.__homePageData__ = (\\{.*\\})", Pattern.DOTALL).matcher(body);
var body = response.body().string();
var m = Pattern.compile("window\\.__homePageData__ = (\\{.*\\})", Pattern.DOTALL).matcher(body);
if (m.find()) {
JSONObject data = new JSONObject(m.group(1));
JSONArray modelData = data.getJSONArray("models");
var data = new JSONObject(m.group(1));
var modelData = data.getJSONArray("models");
LOG.debug("Found {} models", modelData.length());
for (int i = 0; i < modelData.length(); i++) {
JSONObject modelJson = modelData.getJSONObject(i);
for (var i = 0; i < modelData.length(); i++) {
var modelJson = modelData.getJSONObject(i);
try {
Flirt4FreeModel model = parseModel(modelJson);
if (model != null) {
models.add(model);
}
models.add(model);
} catch(Exception e) {
LOG.warn("Couldn't parse model {}", modelJson);
}
}
return models.stream()
.filter(filter)
.skip((page - 1) * MODELS_PER_PAGE)
.skip((page - 1) * (long)MODELS_PER_PAGE)
.limit(MODELS_PER_PAGE)
.collect(Collectors.toList());
} else {
@ -90,14 +86,14 @@ public class Flirt4FreeUpdateService extends PaginatedScheduledService {
}
private Flirt4FreeModel parseModel(JSONObject modelData) {
String name = modelData.getString("model_seo_name");
var name = modelData.getString("model_seo_name");
Flirt4FreeModel model = (Flirt4FreeModel) flirt4Free.createModel(name);
model.setDisplayName(modelData.getString("display"));
model.setDescription(modelData.getString("topic"));
model.setUrl(Flirt4Free.BASE_URI + "/rooms/" + model.getName() + '/');
model.setNew(modelData.optString("is_new", "0").equals("1"));
String videoHost = modelData.getString("video_host");
String modelId = modelData.getString("model_id");
var videoHost = modelData.getString("video_host");
var modelId = modelData.getString("model_id");
model.setId(modelId);
String streamUrl = "https://manifest.vscdns.com/manifest.m3u8.m3u8?key=nil&provider=level3&secure=true&host=" + videoHost
+ "&model_id=" + modelId;

View File

@ -1,7 +1,6 @@
package ctbrec.ui.sites.jasmin;
import ctbrec.Config;
import ctbrec.Settings;
import ctbrec.sites.jasmin.LiveJasmin;
import ctbrec.ui.DesktopIntegration;
import ctbrec.ui.settings.SettingsTab;
@ -25,15 +24,15 @@ public class LiveJasminConfigUi extends AbstractConfigUI {
@Override
public Parent createConfigPanel() {
Settings settings = Config.getInstance().getSettings();
GridPane layout = SettingsTab.createGridLayout();
var settings = Config.getInstance().getSettings();
var layout = SettingsTab.createGridLayout();
int row = 0;
Label l = new Label("Active");
var row = 0;
var l = new Label("Active");
layout.add(l, 0, row);
CheckBox enabled = new CheckBox();
var enabled = new CheckBox();
enabled.setSelected(!settings.disabledSites.contains(liveJasmin.getName()));
enabled.setOnAction((e) -> {
enabled.setOnAction(e -> {
if(enabled.isSelected()) {
settings.disabledSites.remove(liveJasmin.getName());
} else {
@ -45,7 +44,7 @@ public class LiveJasminConfigUi extends AbstractConfigUI {
layout.add(enabled, 1, row++);
layout.add(new Label("LiveJasmin User"), 0, row);
TextField username = new TextField(Config.getInstance().getSettings().livejasminUsername);
var username = new TextField(Config.getInstance().getSettings().livejasminUsername);
username.textProperty().addListener((ob, o, n) -> {
if(!n.equals(Config.getInstance().getSettings().livejasminUsername)) {
Config.getInstance().getSettings().livejasminUsername = n;
@ -59,7 +58,7 @@ public class LiveJasminConfigUi extends AbstractConfigUI {
layout.add(username, 1, row++);
layout.add(new Label("LiveJasmin Password"), 0, row);
PasswordField password = new PasswordField();
var password = new PasswordField();
password.setText(Config.getInstance().getSettings().livejasminPassword);
password.textProperty().addListener((ob, o, n) -> {
if(!n.equals(Config.getInstance().getSettings().livejasminPassword)) {
@ -74,7 +73,7 @@ public class LiveJasminConfigUi extends AbstractConfigUI {
layout.add(password, 1, row++);
layout.add(new Label("LiveJasmin Base URL"), 0, row);
TextField baseUrl = new TextField();
var baseUrl = new TextField();
baseUrl.setText(Config.getInstance().getSettings().livejasminBaseUrl);
baseUrl.textProperty().addListener((ob, o, n) -> {
Config.getInstance().getSettings().livejasminBaseUrl = baseUrl.getText();
@ -85,9 +84,9 @@ public class LiveJasminConfigUi extends AbstractConfigUI {
GridPane.setColumnSpan(baseUrl, 2);
layout.add(baseUrl, 1, row++);
Button createAccount = new Button("Create new Account");
createAccount.setOnAction((e) -> DesktopIntegration.open(liveJasmin.getAffiliateLink()));
layout.add(createAccount, 1, row++);
var createAccount = new Button("Create new Account");
createAccount.setOnAction(e -> DesktopIntegration.open(liveJasmin.getAffiliateLink()));
layout.add(createAccount, 1, row);
GridPane.setColumnSpan(createAccount, 2);
GridPane.setMargin(username, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
GridPane.setMargin(password, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));

View File

@ -4,7 +4,6 @@ import java.io.IOException;
import java.util.Collections;
import java.util.function.Consumer;
import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -19,23 +18,24 @@ import okhttp3.HttpUrl;
public class LiveJasminElectronLoginDialog {
private static final transient Logger LOG = LoggerFactory.getLogger(LiveJasminElectronLoginDialog.class);
private static final Logger LOG = LoggerFactory.getLogger(LiveJasminElectronLoginDialog.class);
public static final String URL = LiveJasmin.baseUrl + "/en/auth/login";
private CookieJar cookieJar;
private ExternalBrowser browser;
public LiveJasminElectronLoginDialog(CookieJar cookieJar) throws Exception {
public LiveJasminElectronLoginDialog(CookieJar cookieJar) throws IOException {
this.cookieJar = cookieJar;
browser = ExternalBrowser.getInstance();
try {
JSONObject config = new JSONObject();
var config = new JSONObject();
config.put("url", URL);
config.put("w", 640);
config.put("h", 720);
JSONObject msg = new JSONObject();
var msg = new JSONObject();
msg.put("config", config);
browser.run(msg, msgHandler);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new IOException("Couldn't wait for login dialog", e);
} catch (IOException e) {
LOG.debug("Error while starting the browser or communication to it", e);
@ -44,14 +44,13 @@ public class LiveJasminElectronLoginDialog {
}
}
private Consumer<String> msgHandler = (line) -> {
//LOG.debug("Browser: {}", line);
private Consumer<String> msgHandler = line -> {
if(!line.startsWith("{")) {
System.err.println(line);
System.err.println(line); // NOSONAR
} else {
JSONObject json = new JSONObject(line);
var json = new JSONObject(line);
if(json.has("url")) {
String url = json.getString("url");
var url = json.getString("url");
if(url.endsWith("/auth/login")) {
try {
String username = Config.getInstance().getSettings().livejasminUsername;
@ -73,9 +72,9 @@ public class LiveJasminElectronLoginDialog {
}
}
if(json.has("cookies")) {
JSONArray _cookies = json.getJSONArray("cookies");
for (int i = 0; i < _cookies.length(); i++) {
JSONObject cookie = _cookies.getJSONObject(i);
var cookiesFromBrowser = json.getJSONArray("cookies");
for (var i = 0; i < cookiesFromBrowser.length(); i++) {
var cookie = cookiesFromBrowser.getJSONObject(i);
Builder b = new Cookie.Builder()
.path("/")
.domain(LiveJasmin.baseDomain)

View File

@ -15,10 +15,8 @@ public class LiveJasminFollowedTab extends LiveJasminTab implements FollowedTab
@Override
public void setScene(Scene scene) {
scene.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
if(this.isSelected()) {
if(event.getCode() == KeyCode.DELETE) {
follow(selectedThumbCells, false);
}
if (this.isSelected() && event.getCode() == KeyCode.DELETE) {
follow(selectedThumbCells, false);
}
});
}

View File

@ -23,7 +23,6 @@ import ctbrec.ui.SiteUiFactory;
import ctbrec.ui.tabs.PaginatedScheduledService;
import javafx.concurrent.Task;
import okhttp3.Request;
import okhttp3.Response;
public class LiveJasminFollowedUpdateService extends PaginatedScheduledService {
@ -50,16 +49,16 @@ public class LiveJasminFollowedUpdateService extends PaginatedScheduledService {
throw new NotLoggedInExcetion("Couldn't login to livejasmin");
}
LOG.debug("Fetching page {}", url);
Request request = new Request.Builder()
var request = new Request.Builder()
.url(url)
.header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent)
.header(ACCEPT, "*/*")
.header(ACCEPT_LANGUAGE, Locale.ENGLISH.getLanguage())
.header(REFERER, liveJasmin.getBaseUrl())
.build();
try (Response response = liveJasmin.getHttpClient().execute(request)) {
try (var response = liveJasmin.getHttpClient().execute(request)) {
if (response.isSuccessful()) {
String body = response.body().string();
var body = response.body().string();
List<Model> models = new ArrayList<>();
Elements modelCells = getTags(body, "article[class~=perf_container]");
for (Element modelCell : modelCells) {

View File

@ -41,7 +41,7 @@ public class LiveJasminSiteUi extends AbstractSiteUi {
public synchronized boolean login() throws IOException {
// renew login every 30 min
long now = System.currentTimeMillis();
boolean renew = false;
var renew = false;
if ((now - lastLoginTime) > TimeUnit.MINUTES.toMillis(30)) {
renew = true;
}

View File

@ -2,6 +2,9 @@ package ctbrec.ui.sites.jasmin;
import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ctbrec.Config;
import ctbrec.sites.Site;
import ctbrec.ui.tabs.PaginatedScheduledService;
@ -14,6 +17,7 @@ import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
public class LiveJasminTab extends ThumbOverviewTab {
private static final Logger LOG = LoggerFactory.getLogger(LiveJasminTab.class);
protected Label status;
protected Button acknowledge = new Button("That's alright");
private boolean betaAcknowledged = Config.getInstance().getSettings().livejasminBetaAcknowledged;
@ -36,6 +40,7 @@ public class LiveJasminTab extends ThumbOverviewTab {
try {
Config.getInstance().save();
} catch (IOException e1) {
LOG.error("Couldn't save config", e1);
}
status.setText("Loading...");
grid.getChildren().remove(acknowledge);
@ -47,11 +52,6 @@ public class LiveJasminTab extends ThumbOverviewTab {
});
}
@Override
protected void createGui() {
super.createGui();
}
@Override
protected void onSuccess() {
if(Config.getInstance().getSettings().livejasminBetaAcknowledged) {
@ -70,17 +70,10 @@ public class LiveJasminTab extends ThumbOverviewTab {
}
}
@Override
public void selected() {
super.selected();
}
public void setScene(Scene scene) {
scene.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
if(this.isSelected()) {
if(event.getCode() == KeyCode.DELETE) {
follow(selectedThumbCells, false);
}
if (this.isSelected() && event.getCode() == KeyCode.DELETE) {
follow(selectedThumbCells, false);
}
});
}

View File

@ -10,7 +10,7 @@ import javafx.scene.Scene;
import javafx.scene.control.Tab;
import javafx.util.Duration;
public class LiveJasminTabProvider extends TabProvider {
public class LiveJasminTabProvider implements TabProvider {
private LiveJasmin liveJasmin;
private LiveJasminFollowedTab followedTab;
@ -43,7 +43,7 @@ public class LiveJasminTabProvider extends TabProvider {
}
private ThumbOverviewTab createTab(String title, String url) {
LiveJasminUpdateService s = new LiveJasminUpdateService(liveJasmin, url);
var s = new LiveJasminUpdateService(liveJasmin, url);
s.setPeriod(Duration.seconds(60));
ThumbOverviewTab tab = new LiveJasminTab(title, s, liveJasmin);
tab.setRecorder(liveJasmin.getRecorder());

View File

@ -8,25 +8,21 @@ import java.util.Collections;
import java.util.List;
import java.util.Locale;
import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ctbrec.Config;
import ctbrec.Model;
import ctbrec.io.CookieJarImpl;
import ctbrec.io.HttpException;
import ctbrec.sites.jasmin.LiveJasmin;
import ctbrec.sites.jasmin.LiveJasminModel;
import ctbrec.ui.SiteUI;
import ctbrec.ui.SiteUiFactory;
import ctbrec.ui.tabs.PaginatedScheduledService;
import javafx.concurrent.Task;
import okhttp3.Cookie;
import okhttp3.HttpUrl;
import okhttp3.Request;
import okhttp3.Response;
public class LiveJasminUpdateService extends PaginatedScheduledService {
@ -45,8 +41,8 @@ public class LiveJasminUpdateService extends PaginatedScheduledService {
@Override
public List<Model> call() throws IOException {
// sort by popularity
CookieJarImpl cookieJar = liveJasmin.getHttpClient().getCookieJar();
Cookie sortCookie = new Cookie.Builder()
var cookieJar = liveJasmin.getHttpClient().getCookieJar();
var sortCookie = new Cookie.Builder()
.domain(LiveJasmin.baseDomain)
.name("listPageOrderType")
.value("most_popular")
@ -55,7 +51,7 @@ public class LiveJasminUpdateService extends PaginatedScheduledService {
// TODO find out how to switch pages
LOG.debug("Fetching page {}", url);
Request request = new Request.Builder()
var request = new Request.Builder()
.url(url)
.addHeader(USER_AGENT, Config.getInstance().getSettings().httpUserAgent)
.addHeader(ACCEPT, MIMETYPE_APPLICATION_JSON)
@ -63,31 +59,16 @@ public class LiveJasminUpdateService extends PaginatedScheduledService {
.addHeader(REFERER, liveJasmin.getBaseUrl())
.addHeader(X_REQUESTED_WITH, XML_HTTP_REQUEST)
.build();
try (Response response = liveJasmin.getHttpClient().execute(request)) {
try (var response = liveJasmin.getHttpClient().execute(request)) {
LOG.debug("Response {} {}", response.code(), response.message());
if (response.isSuccessful()) {
String body = response.body().string();
var body = response.body().string();
List<Model> models = new ArrayList<>();
JSONObject json = new JSONObject(body);
//LOG.debug(json.toString(2));
var json = new JSONObject(body);
if(json.optBoolean("success")) {
JSONObject data = json.getJSONObject("data");
JSONObject content = data.getJSONObject("content");
JSONArray performers = content.getJSONArray("performers");
for (int i = 0; i < performers.length(); i++) {
JSONObject m = performers.getJSONObject(i);
String name = m.optString("pid");
if(name.isEmpty()) {
continue;
}
LiveJasminModel model = (LiveJasminModel) liveJasmin.createModel(name);
model.setId(m.getString("id"));
model.setPreview(m.getString("profilePictureUrl"));
model.setOnlineState(LiveJasminModel.mapStatus(m.optInt("status")));
models.add(model);
}
parseModels(models, json);
} else if(json.optString("error").equals("Please login.")) {
SiteUI siteUI = SiteUiFactory.getUi(liveJasmin);
var siteUI = SiteUiFactory.getUi(liveJasmin);
if(siteUI.login()) {
return call();
} else {
@ -106,4 +87,22 @@ public class LiveJasminUpdateService extends PaginatedScheduledService {
}
};
}
private void parseModels(List<Model> models, JSONObject json) {
var data = json.getJSONObject("data");
var content = data.getJSONObject("content");
var performers = content.getJSONArray("performers");
for (var i = 0; i < performers.length(); i++) {
var m = performers.getJSONObject(i);
var name = m.optString("pid");
if(name.isEmpty()) {
continue;
}
LiveJasminModel model = (LiveJasminModel) liveJasmin.createModel(name);
model.setId(m.getString("id"));
model.setPreview(m.getString("profilePictureUrl"));
model.setOnlineState(LiveJasminModel.mapStatus(m.optInt("status")));
models.add(model);
}
}
}

View File

@ -1,7 +1,6 @@
package ctbrec.ui.sites.manyvids;
import ctbrec.Config;
import ctbrec.Settings;
import ctbrec.sites.manyvids.MVLive;
import ctbrec.ui.settings.SettingsTab;
import ctbrec.ui.sites.AbstractConfigUI;
@ -20,15 +19,15 @@ public class MVLiveConfigUi extends AbstractConfigUI {
@Override
public Parent createConfigPanel() {
Settings settings = Config.getInstance().getSettings();
var settings = Config.getInstance().getSettings();
GridPane layout = SettingsTab.createGridLayout();
int row = 0;
Label l = new Label("Active");
var row = 0;
var l = new Label("Active");
layout.add(l, 0, row);
CheckBox enabled = new CheckBox();
var enabled = new CheckBox();
enabled.setSelected(!settings.disabledSites.contains(site.getName()));
enabled.setOnAction((e) -> {
enabled.setOnAction(e -> {
if(enabled.isSelected()) {
settings.disabledSites.remove(site.getName());
} else {
@ -37,7 +36,7 @@ public class MVLiveConfigUi extends AbstractConfigUI {
save();
});
GridPane.setMargin(enabled, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
layout.add(enabled, 1, row++);
layout.add(enabled, 1, row);
return layout;
}
}

View File

@ -9,7 +9,7 @@ import ctbrec.ui.tabs.ThumbOverviewTab;
import javafx.scene.Scene;
import javafx.scene.control.Tab;
public class MVLiveTabProvider extends TabProvider {
public class MVLiveTabProvider implements TabProvider {
private MVLive mvlive;
@ -26,8 +26,8 @@ public class MVLiveTabProvider extends TabProvider {
}
private Tab createTab(String title) {
MVLiveUpdateService updateService = new MVLiveUpdateService(mvlive);
ThumbOverviewTab tab = new ThumbOverviewTab(title, updateService, mvlive);
var updateService = new MVLiveUpdateService(mvlive);
var tab = new ThumbOverviewTab(title, updateService, mvlive);
tab.setRecorder(mvlive.getRecorder());
tab.setImageAspectRatio(1);
return tab;

View File

@ -57,50 +57,59 @@ public class FriendsUpdateService extends PaginatedScheduledService {
.build();
try (Response resp = myFreeCams.getHttpClient().execute(req)) {
if (resp.isSuccessful()) {
String body = resp.body().string().substring(4);
try {
JSONObject json = new JSONObject(body);
for (String key : json.keySet()) {
int uid = Integer.parseInt(key);
MyFreeCamsModel model = MyFreeCamsClient.getInstance().getModel(uid);
if (model == null) {
JSONObject modelObject = json.getJSONObject(key);
String name = modelObject.getString("u");
model = myFreeCams.createModel(name);
SessionState st = new SessionState();
st.setM(new ctbrec.sites.mfc.Model());
st.getM().setCamscore(0.0);
st.setU(new User());
st.setUid(uid);
st.setLv(modelObject.getInt("lv"));
st.setVs(127);
}
models.add(model);
}
} catch (Exception e) {
LOG.info("Exception getting friends list. Response was: {}", body, e);
}
var body = resp.body().string().substring(4);
parseModels(body, models);
} else {
LOG.error("Couldn't load friends list {} {}", resp.code(), resp.message());
}
}
boolean filterOnline = mode == Mode.ONLINE;
return models.stream().filter(m -> {
try {
return m.isOnline() == filterOnline;
} catch (Exception e) {
return false;
}
})
return models.stream()
.filter(m -> {
try {
return m.isOnline() == filterOnline;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return false;
} catch (Exception e) {
return false;
}
})
.sorted((m1, m2) -> (int) (m2.getCamScore() - m1.getCamScore()))
.skip((page - 1) * 50l)
.limit(50)
.collect(Collectors.toList());
}
}
};
}
private void parseModels(String body, List<MyFreeCamsModel> models) {
try {
var json = new JSONObject(body);
for (String key : json.keySet()) {
var uid = Integer.parseInt(key);
MyFreeCamsModel model = MyFreeCamsClient.getInstance().getModel(uid);
if (model == null) {
var modelObject = json.getJSONObject(key);
var name = modelObject.getString("u");
model = myFreeCams.createModel(name);
var st = new SessionState();
st.setM(new ctbrec.sites.mfc.Model());
st.getM().setCamscore(0.0);
st.setU(new User());
st.setUid(uid);
st.setLv(modelObject.getInt("lv"));
st.setVs(127);
}
models.add(model);
}
} catch (Exception e) {
LOG.info("Exception getting friends list. Response was: {}", body, e);
}
}
public void setMode(Mode mode) {
this.mode = mode;
}

View File

@ -20,8 +20,8 @@ public class HDCamsUpdateService extends PaginatedScheduledService {
return new Task<List<Model>>() {
@Override
public List<Model> call() throws IOException {
MyFreeCamsClient client = MyFreeCamsClient.getInstance();
int modelsPerPage = 50;
var client = MyFreeCamsClient.getInstance();
var modelsPerPage = 50;
return client.getModels().stream()
.filter(m -> m.getPreview() != null)
@ -33,7 +33,10 @@ public class HDCamsUpdateService extends PaginatedScheduledService {
.filter(m -> {
try {
return m.isOnline();
} catch(Exception e) {
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return false;
} catch (Exception e) {
return false;
}
})

Some files were not shown because too many files have changed in this diff Show More