forked from j62/ctbrec
Code cleanup
This commit is contained in:
parent
7d23ebccfe
commit
ea062582d4
|
@ -11,11 +11,7 @@
|
||||||
<attribute name="maven.pomderived" value="true"/>
|
<attribute name="maven.pomderived" value="true"/>
|
||||||
</attributes>
|
</attributes>
|
||||||
</classpathentry>
|
</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.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.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||||
<attributes>
|
<attributes>
|
||||||
<attribute name="maven.pomderived" value="true"/>
|
<attribute name="maven.pomderived" value="true"/>
|
||||||
|
|
|
@ -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.enumIdentifier=error
|
||||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
||||||
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=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
|
org.eclipse.jdt.core.compiler.source=15
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package ctbrec.docs;
|
package ctbrec.docs;
|
||||||
|
|
||||||
|
import static java.nio.charset.StandardCharsets.*;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
|
@ -7,7 +9,6 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLDecoder;
|
import java.net.URLDecoder;
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -32,13 +33,13 @@ public abstract class AbstractDocServlet extends HttpServlet {
|
||||||
if(resourceAsStream == null) {
|
if(resourceAsStream == null) {
|
||||||
throw new FileNotFoundException();
|
throw new FileNotFoundException();
|
||||||
}
|
}
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
var out = new ByteArrayOutputStream();
|
||||||
int length = 0;
|
var length = 0;
|
||||||
byte[] buffer = new byte[1024];
|
var buffer = new byte[1024];
|
||||||
while( (length = resourceAsStream.read(buffer)) >= 0 ) {
|
while( (length = resourceAsStream.read(buffer)) >= 0 ) {
|
||||||
out.write(buffer, 0, length);
|
out.write(buffer, 0, length);
|
||||||
}
|
}
|
||||||
return new String(out.toByteArray(), "utf-8");
|
return new String(out.toByteArray(), UTF_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
String getHeader() throws IOException {
|
String getHeader() throws IOException {
|
||||||
|
@ -66,15 +67,15 @@ public abstract class AbstractDocServlet extends HttpServlet {
|
||||||
|
|
||||||
private void indexJar(URL resource, List<String> pages) throws IOException {
|
private void indexJar(URL resource, List<String> pages) throws IOException {
|
||||||
String fileUrl = resource.getFile();
|
String fileUrl = resource.getFile();
|
||||||
fileUrl = URLDecoder.decode(fileUrl, StandardCharsets.UTF_8);
|
fileUrl = URLDecoder.decode(fileUrl, UTF_8);
|
||||||
int colon = fileUrl.indexOf(':');
|
int colon = fileUrl.indexOf(':');
|
||||||
int exclamation = fileUrl.indexOf('!');
|
int exclamation = fileUrl.indexOf('!');
|
||||||
String jar = fileUrl.substring(colon + 1, exclamation);
|
var jar = fileUrl.substring(colon + 1, exclamation);
|
||||||
String internalFile = fileUrl.substring(exclamation + 2);
|
var internalFile = fileUrl.substring(exclamation + 2);
|
||||||
try (JarFile jarFile = new JarFile(jar)) {
|
try (var jarFile = new JarFile(jar)) {
|
||||||
Enumeration<JarEntry> entries = jarFile.entries();
|
Enumeration<JarEntry> entries = jarFile.entries();
|
||||||
while (entries.hasMoreElements()) {
|
while (entries.hasMoreElements()) {
|
||||||
JarEntry jarEntry = entries.nextElement();
|
var jarEntry = entries.nextElement();
|
||||||
String name = jarEntry.getName();
|
String name = jarEntry.getName();
|
||||||
if (name.startsWith(internalFile) && name.toLowerCase().endsWith(".md")) {
|
if (name.startsWith(internalFile) && name.toLowerCase().endsWith(".md")) {
|
||||||
pages.add(name.substring(name.lastIndexOf('/') + 1));
|
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) {
|
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"));
|
String[] files = docs.list((dir, name) -> name.toLowerCase().endsWith(".md"));
|
||||||
pages.addAll(Arrays.asList(files));
|
pages.addAll(Arrays.asList(files));
|
||||||
}
|
}
|
||||||
|
@ -94,15 +95,19 @@ public abstract class AbstractDocServlet extends HttpServlet {
|
||||||
return loadFile(resource);
|
return loadFile(resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void error(HttpServletResponse resp, int status, String message) throws IOException {
|
protected void error(HttpServletResponse resp, int status, String message) {
|
||||||
resp.setStatus(status);
|
try {
|
||||||
resp.getWriter().println(getHeader());
|
resp.setStatus(status);
|
||||||
String html = loadFile("/html/docs/" + status + ".html");
|
resp.getWriter().println(getHeader());
|
||||||
if(message == null || message.trim().isEmpty()) {
|
String html = loadFile("/html/docs/" + status + ".html");
|
||||||
message = "";
|
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());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,40 +16,41 @@ import org.slf4j.LoggerFactory;
|
||||||
import ctbrec.servlet.StaticFileServlet;
|
import ctbrec.servlet.StaticFileServlet;
|
||||||
|
|
||||||
public class DocServer {
|
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;
|
private static volatile boolean started = false;
|
||||||
|
|
||||||
public synchronized static void start() throws Exception {
|
private DocServer() {}
|
||||||
|
|
||||||
|
public static synchronized void start() throws Exception {
|
||||||
if(started) {
|
if(started) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
started = true;
|
started = true;
|
||||||
server = new Server();
|
var server = new Server();
|
||||||
|
|
||||||
HttpConfiguration config = new HttpConfiguration();
|
var config = new HttpConfiguration();
|
||||||
config.setSendServerVersion(false);
|
config.setSendServerVersion(false);
|
||||||
ServerConnector http = new ServerConnector(server, new HttpConnectionFactory(config));
|
var http = new ServerConnector(server, new HttpConnectionFactory(config));
|
||||||
http.setPort(5689);
|
http.setPort(5689);
|
||||||
server.addConnector(http);
|
server.addConnector(http);
|
||||||
|
|
||||||
ServletHandler handler = new ServletHandler();
|
var handler = new ServletHandler();
|
||||||
server.setHandler(handler);
|
server.setHandler(handler);
|
||||||
HandlerList handlers = new HandlerList();
|
var handlers = new HandlerList();
|
||||||
handlers.setHandlers(new Handler[] { handler });
|
handlers.setHandlers(new Handler[] { handler });
|
||||||
server.setHandler(handlers);
|
server.setHandler(handlers);
|
||||||
|
|
||||||
MarkdownServlet markdownServlet = new MarkdownServlet();
|
var markdownServlet = new MarkdownServlet();
|
||||||
ServletHolder holder = new ServletHolder(markdownServlet);
|
var holder = new ServletHolder(markdownServlet);
|
||||||
handler.addServletWithMapping(holder, "/docs/*");
|
handler.addServletWithMapping(holder, "/docs/*");
|
||||||
|
|
||||||
AbstractDocServlet searchServlet = new SearchServlet();
|
AbstractDocServlet searchServlet = new SearchServlet();
|
||||||
holder = new ServletHolder(searchServlet);
|
holder = new ServletHolder(searchServlet);
|
||||||
handler.addServletWithMapping(holder, "/search/*");
|
handler.addServletWithMapping(holder, "/search/*");
|
||||||
|
|
||||||
StaticFileServlet staticFileServlet = new StaticFileServlet("/html", false);
|
var staticFileServlet = new StaticFileServlet("/html", false);
|
||||||
holder = new ServletHolder(staticFileServlet);
|
holder = new ServletHolder(staticFileServlet);
|
||||||
handler.addServletWithMapping(holder, "/static/*");
|
handler.addServletWithMapping(holder, "/static/*");
|
||||||
|
|
||||||
|
|
|
@ -38,16 +38,18 @@ public class MarkdownServlet extends AbstractDocServlet {
|
||||||
}
|
}
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
error(resp, HttpServletResponse.SC_NOT_FOUND, "");
|
error(resp, HttpServletResponse.SC_NOT_FOUND, "");
|
||||||
|
} catch (Exception e) {
|
||||||
|
error(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void listPages(HttpServletResponse resp) throws IOException {
|
private void listPages(HttpServletResponse resp) throws IOException {
|
||||||
List<String> pages = getPages();
|
List<String> pages = getPages();
|
||||||
String html = "<ul>";
|
var html = new StringBuilder("<ul>");
|
||||||
for (String page : pages) {
|
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.setStatus(HttpServletResponse.SC_OK);
|
||||||
resp.getWriter().println(getHeader());
|
resp.getWriter().println(getHeader());
|
||||||
resp.getWriter().println(html);
|
resp.getWriter().println(html);
|
||||||
|
@ -55,8 +57,8 @@ public class MarkdownServlet extends AbstractDocServlet {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String markdownToHtml(String markdown) {
|
private String markdownToHtml(String markdown) {
|
||||||
MutableDataSet options = new MutableDataSet();
|
var options = new MutableDataSet();
|
||||||
Parser parser = Parser.builder(options).build();
|
var parser = Parser.builder(options).build();
|
||||||
HtmlRenderer renderer = HtmlRenderer.builder(options).build();
|
HtmlRenderer renderer = HtmlRenderer.builder(options).build();
|
||||||
Node document = parser.parse(markdown);
|
Node document = parser.parse(markdown);
|
||||||
String html = renderer.render(document);
|
String html = renderer.render(document);
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package ctbrec.docs;
|
package ctbrec.docs;
|
||||||
|
|
||||||
|
import static javax.servlet.http.HttpServletResponse.*;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -9,41 +11,55 @@ import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public class SearchServlet extends AbstractDocServlet {
|
public class SearchServlet extends AbstractDocServlet {
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(SearchServlet.class);
|
||||||
private static final String Q = "term";
|
private static final String Q = "term";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||||
if(req.getParameter(Q) == null) {
|
try {
|
||||||
error(resp, HttpServletResponse.SC_BAD_REQUEST, "Parameter \""+Q+"\" is missing");
|
if (req.getParameter(Q) == null) {
|
||||||
return;
|
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);
|
private void searchPages(JSONArray result, List<String> pages, String[] tokens) throws IOException {
|
||||||
resp.setContentType("application/json");
|
|
||||||
JSONArray result = new JSONArray();
|
|
||||||
List<String> pages = getPages();
|
|
||||||
|
|
||||||
String q = req.getParameter(Q).toLowerCase();
|
|
||||||
String[] tokens = q.split("\\s+");
|
|
||||||
for (String page : pages) {
|
for (String page : pages) {
|
||||||
try {
|
try {
|
||||||
String content = loadMarkdown("/docs/" + page).toLowerCase();
|
String content = loadMarkdown("/docs/" + page).toLowerCase();
|
||||||
boolean allFound = true;
|
var allFound = true;
|
||||||
for (String token : tokens) {
|
for (String token : tokens) {
|
||||||
if(!content.contains(token)) {
|
if (!content.contains(token)) {
|
||||||
allFound = false;
|
allFound = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(allFound) {
|
if (allFound) {
|
||||||
result.put(page);
|
result.put(page);
|
||||||
}
|
}
|
||||||
} catch(FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
// virtual page like index.md -> ignore
|
// virtual page like index.md -> ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
resp.getWriter().println(result.toString());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ public class AutosizeAlert extends Alert {
|
||||||
setResizable(true);
|
setResizable(true);
|
||||||
getDialogPane().setMinHeight(Region.USE_PREF_SIZE);
|
getDialogPane().setMinHeight(Region.USE_PREF_SIZE);
|
||||||
if(parent != null) {
|
if(parent != null) {
|
||||||
Stage stage = (Stage) getDialogPane().getScene().getWindow();
|
var stage = (Stage) getDialogPane().getScene().getWindow();
|
||||||
stage.getScene().getStylesheets().addAll(parent.getStylesheets());
|
stage.getScene().getStylesheets().addAll(parent.getStylesheets());
|
||||||
InputStream icon = Dialogs.class.getResourceAsStream("/icon.png");
|
InputStream icon = Dialogs.class.getResourceAsStream("/icon.png");
|
||||||
stage.getIcons().add(new Image(icon));
|
stage.getIcons().add(new Image(icon));
|
||||||
|
|
|
@ -86,7 +86,6 @@ import javafx.scene.paint.Color;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
import javafx.stage.WindowEvent;
|
import javafx.stage.WindowEvent;
|
||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
import okhttp3.Response;
|
|
||||||
|
|
||||||
public class CamrecApplication extends Application {
|
public class CamrecApplication extends Application {
|
||||||
|
|
||||||
|
@ -104,7 +103,6 @@ public class CamrecApplication extends Application {
|
||||||
public static HttpClient httpClient;
|
public static HttpClient httpClient;
|
||||||
public static String title;
|
public static String title;
|
||||||
private Stage primaryStage;
|
private Stage primaryStage;
|
||||||
private RecordedTab modelsTab;
|
|
||||||
private RecordingsTab recordingsTab;
|
private RecordingsTab recordingsTab;
|
||||||
private ScheduledExecutorService scheduler;
|
private ScheduledExecutorService scheduler;
|
||||||
private int activeRecordings = 0;
|
private int activeRecordings = 0;
|
||||||
|
@ -114,7 +112,7 @@ public class CamrecApplication extends Application {
|
||||||
public void start(Stage primaryStage) throws Exception {
|
public void start(Stage primaryStage) throws Exception {
|
||||||
this.primaryStage = primaryStage;
|
this.primaryStage = primaryStage;
|
||||||
scheduler = Executors.newScheduledThreadPool(1, r -> {
|
scheduler = Executors.newScheduledThreadPool(1, r -> {
|
||||||
Thread t = new Thread(r);
|
var t = new Thread(r);
|
||||||
t.setDaemon(true);
|
t.setDaemon(true);
|
||||||
t.setName("Scheduler");
|
t.setName("Scheduler");
|
||||||
return t;
|
return t;
|
||||||
|
@ -172,7 +170,7 @@ public class CamrecApplication extends Application {
|
||||||
|
|
||||||
private void registerClipboardListener() {
|
private void registerClipboardListener() {
|
||||||
if (config.getSettings().monitorClipboard) {
|
if (config.getSettings().monitorClipboard) {
|
||||||
ClipboardListener clipboardListener = new ClipboardListener(recorder, sites);
|
var clipboardListener = new ClipboardListener(recorder, sites);
|
||||||
scheduler.scheduleAtFixedRate(clipboardListener, 0, 1, TimeUnit.SECONDS);
|
scheduler.scheduleAtFixedRate(clipboardListener, 0, 1, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -209,19 +207,19 @@ public class CamrecApplication extends Application {
|
||||||
int windowWidth = Config.getInstance().getSettings().windowWidth;
|
int windowWidth = Config.getInstance().getSettings().windowWidth;
|
||||||
int windowHeight = Config.getInstance().getSettings().windowHeight;
|
int windowHeight = Config.getInstance().getSettings().windowHeight;
|
||||||
|
|
||||||
Scene scene = new Scene(rootPane, windowWidth, windowHeight);
|
var scene = new Scene(rootPane, windowWidth, windowHeight);
|
||||||
primaryStage.setScene(scene);
|
primaryStage.setScene(scene);
|
||||||
Dialogs.setScene(scene);
|
Dialogs.setScene(scene);
|
||||||
rootPane.setCenter(tabPane);
|
rootPane.setCenter(tabPane);
|
||||||
rootPane.setBottom(statusBar);
|
rootPane.setBottom(statusBar);
|
||||||
for (Site site : sites) {
|
for (Site site : sites) {
|
||||||
if (site.isEnabled()) {
|
if (site.isEnabled()) {
|
||||||
SiteTab siteTab = new SiteTab(site, scene);
|
var siteTab = new SiteTab(site, scene);
|
||||||
tabPane.getTabs().add(siteTab);
|
tabPane.getTabs().add(siteTab);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
modelsTab = new RecordedTab(recorder, sites);
|
var modelsTab = new RecordedTab(recorder, sites);
|
||||||
tabPane.getTabs().add(modelsTab);
|
tabPane.getTabs().add(modelsTab);
|
||||||
recordingsTab = new RecordingsTab("Recordings", recorder, config);
|
recordingsTab = new RecordingsTab("Recordings", recorder, config);
|
||||||
tabPane.getTabs().add(recordingsTab);
|
tabPane.getTabs().add(recordingsTab);
|
||||||
|
@ -236,7 +234,7 @@ public class CamrecApplication extends Application {
|
||||||
|
|
||||||
switchToStartTab();
|
switchToStartTab();
|
||||||
writeColorSchemeStyleSheet();
|
writeColorSchemeStyleSheet();
|
||||||
Color base = Color.web(Config.getInstance().getSettings().colorBase);
|
var base = Color.web(Config.getInstance().getSettings().colorBase);
|
||||||
if (!base.equals(Color.WHITE)) {
|
if (!base.equals(Color.WHITE)) {
|
||||||
loadStyleSheet(primaryStage, "color.css");
|
loadStyleSheet(primaryStage, "color.css");
|
||||||
}
|
}
|
||||||
|
@ -308,7 +306,7 @@ public class CamrecApplication extends Application {
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for active recordings
|
// check for active recordings
|
||||||
boolean shutdownNow = false;
|
var shutdownNow = false;
|
||||||
if (config.getSettings().localRecording) {
|
if (config.getSettings().localRecording) {
|
||||||
try {
|
try {
|
||||||
if (!recorder.getCurrentlyRecording().isEmpty()) {
|
if (!recorder.getCurrentlyRecording().isEmpty()) {
|
||||||
|
@ -374,7 +372,7 @@ public class CamrecApplication extends Application {
|
||||||
|
|
||||||
private void registerAlertSystem() {
|
private void registerAlertSystem() {
|
||||||
for (EventHandlerConfiguration eventHandlerConfig : Config.getInstance().getSettings().eventHandlers) {
|
for (EventHandlerConfiguration eventHandlerConfig : Config.getInstance().getSettings().eventHandlers) {
|
||||||
EventHandler handler = new EventHandler(eventHandlerConfig);
|
var handler = new EventHandler(eventHandlerConfig);
|
||||||
EventBusHolder.register(handler);
|
EventBusHolder.register(handler);
|
||||||
LOG.debug("Registered event handler for {} {}", eventHandlerConfig.getEvent(), eventHandlerConfig.getName());
|
LOG.debug("Registered event handler for {} {}", eventHandlerConfig.getEvent(), eventHandlerConfig.getName());
|
||||||
}
|
}
|
||||||
|
@ -428,13 +426,13 @@ public class CamrecApplication extends Application {
|
||||||
bytesPerSecond = 0;
|
bytesPerSecond = 0;
|
||||||
}
|
}
|
||||||
String humanReadable = ByteUnitFormatter.format(bytesPerSecond);
|
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));
|
Platform.runLater(() -> statusLabel.setText(status));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeColorSchemeStyleSheet() {
|
private void writeColorSchemeStyleSheet() {
|
||||||
File colorCss = new File(Config.getInstance().getConfigDir(), "color.css");
|
var colorCss = new File(Config.getInstance().getConfigDir(), "color.css");
|
||||||
try (FileOutputStream fos = new FileOutputStream(colorCss)) {
|
try (var fos = new FileOutputStream(colorCss)) {
|
||||||
String content = ".root {\n" + " -fx-base: " + Config.getInstance().getSettings().colorBase + ";\n" + " -fx-accent: "
|
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"
|
+ 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" + "}";
|
+ " -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) {
|
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()) {
|
if (css.exists() && css.isFile()) {
|
||||||
primaryStage.getScene().getStylesheets().add(css.toURI().toString());
|
primaryStage.getScene().getStylesheets().add(css.toURI().toString());
|
||||||
}
|
}
|
||||||
|
@ -509,20 +507,20 @@ public class CamrecApplication extends Application {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkForUpdates() {
|
private void checkForUpdates() {
|
||||||
Thread updateCheck = new Thread(() -> {
|
var updateCheck = new Thread(() -> {
|
||||||
String url = "https://pastebin.com/raw/mUxtKzyB";
|
var url = "https://pastebin.com/raw/mUxtKzyB";
|
||||||
Request request = new Request.Builder().url(url).build();
|
var request = new Request.Builder().url(url).build();
|
||||||
try (Response response = httpClient.execute(request)) {
|
try (var response = httpClient.execute(request)) {
|
||||||
String body = response.body().string();
|
var body = response.body().string();
|
||||||
LOG.trace("Version check respone: {}", body);
|
LOG.trace("Version check respone: {}", body);
|
||||||
if (response.isSuccessful()) {
|
if (response.isSuccessful()) {
|
||||||
Moshi moshi = new Moshi.Builder().build();
|
var moshi = new Moshi.Builder().build();
|
||||||
Type type = Types.newParameterizedType(List.class, Release.class);
|
Type type = Types.newParameterizedType(List.class, Release.class);
|
||||||
JsonAdapter<List<Release>> adapter = moshi.adapter(type);
|
JsonAdapter<List<Release>> adapter = moshi.adapter(type);
|
||||||
List<Release> releases = adapter.fromJson(body);
|
List<Release> releases = adapter.fromJson(body);
|
||||||
Release latest = releases.get(0);
|
var latest = releases.get(0);
|
||||||
Version latestVersion = latest.getVersion();
|
var latestVersion = latest.getVersion();
|
||||||
Version ctbrecVersion = getVersion();
|
var ctbrecVersion = getVersion();
|
||||||
if (latestVersion.compareTo(ctbrecVersion) > 0) {
|
if (latestVersion.compareTo(ctbrecVersion) > 0) {
|
||||||
LOG.debug("Update available {} < {}", ctbrecVersion, latestVersion);
|
LOG.debug("Update available {} < {}", ctbrecVersion, latestVersion);
|
||||||
Platform.runLater(() -> tabPane.getTabs().add(new UpdateTab(latest)));
|
Platform.runLater(() -> tabPane.getTabs().add(new UpdateTab(latest)));
|
||||||
|
@ -546,8 +544,8 @@ public class CamrecApplication extends Application {
|
||||||
return Version.of("0.0.0-DEV");
|
return Version.of("0.0.0-DEV");
|
||||||
} else {
|
} else {
|
||||||
try (InputStream is = CamrecApplication.class.getClassLoader().getResourceAsStream("version")) {
|
try (InputStream is = CamrecApplication.class.getClassLoader().getResourceAsStream("version")) {
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
|
var reader = new BufferedReader(new InputStreamReader(is));
|
||||||
String versionString = reader.readLine();
|
var versionString = reader.readLine();
|
||||||
return Version.of(versionString);
|
return Version.of(versionString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
package ctbrec.ui;
|
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.io.IOException;
|
||||||
import java.security.InvalidKeyException;
|
import java.security.InvalidKeyException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
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 {
|
public class ClipboardListener implements Runnable {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(ClipboardListener.class);
|
private static final Logger LOG = LoggerFactory.getLogger(ClipboardListener.class);
|
||||||
|
@ -50,7 +50,7 @@ public class ClipboardListener implements Runnable {
|
||||||
|
|
||||||
private void addModelIfUrlMatches(String url) {
|
private void addModelIfUrlMatches(String url) {
|
||||||
for (Site site : sites) {
|
for (Site site : sites) {
|
||||||
Model m = site.createModelFromUrl(url);
|
var m = site.createModelFromUrl(url);
|
||||||
if (m != null) {
|
if (m != null) {
|
||||||
try {
|
try {
|
||||||
recorder.addModel(m);
|
recorder.addModel(m);
|
||||||
|
|
|
@ -2,7 +2,6 @@ package ctbrec.ui;
|
||||||
|
|
||||||
import java.awt.AWTException;
|
import java.awt.AWTException;
|
||||||
import java.awt.Desktop;
|
import java.awt.Desktop;
|
||||||
import java.awt.Image;
|
|
||||||
import java.awt.MenuItem;
|
import java.awt.MenuItem;
|
||||||
import java.awt.PopupMenu;
|
import java.awt.PopupMenu;
|
||||||
import java.awt.SystemTray;
|
import java.awt.SystemTray;
|
||||||
|
@ -65,8 +64,8 @@ public class DesktopIntegration {
|
||||||
}
|
}
|
||||||
|
|
||||||
// try external helpers
|
// try external helpers
|
||||||
String[] externalHelpers = { "kde-open5", "kde-open", "gnome-open", "xdg-open" };
|
var externalHelpers = new String[] { "kde-open5", "kde-open", "gnome-open", "xdg-open" };
|
||||||
Runtime rt = Runtime.getRuntime();
|
var rt = Runtime.getRuntime();
|
||||||
for (String helper : externalHelpers) {
|
for (String helper : externalHelpers) {
|
||||||
try {
|
try {
|
||||||
rt.exec(helper + " " + uri);
|
rt.exec(helper + " " + uri);
|
||||||
|
@ -80,9 +79,9 @@ public class DesktopIntegration {
|
||||||
Alert info = new AutosizeAlert(Alert.AlertType.ERROR);
|
Alert info = new AutosizeAlert(Alert.AlertType.ERROR);
|
||||||
info.setTitle("Open URL");
|
info.setTitle("Open URL");
|
||||||
info.setContentText("Couldn't open URL");
|
info.setContentText("Couldn't open URL");
|
||||||
BorderPane pane = new BorderPane();
|
var pane = new BorderPane();
|
||||||
pane.setTop(new Label());
|
pane.setTop(new Label());
|
||||||
TextField urlField = new TextField(uri);
|
var urlField = new TextField(uri);
|
||||||
urlField.setPadding(new Insets(10));
|
urlField.setPadding(new Insets(10));
|
||||||
urlField.setEditable(false);
|
urlField.setEditable(false);
|
||||||
pane.setCenter(urlField);
|
pane.setCenter(urlField);
|
||||||
|
@ -100,8 +99,8 @@ public class DesktopIntegration {
|
||||||
}
|
}
|
||||||
|
|
||||||
// try external helpers
|
// try external helpers
|
||||||
String[] externalHelpers = { "kde-open5", "kde-open", "gnome-open", "xdg-open" };
|
var externalHelpers = new String[] { "kde-open5", "kde-open", "gnome-open", "xdg-open" };
|
||||||
Runtime rt = Runtime.getRuntime();
|
var rt = Runtime.getRuntime();
|
||||||
for (String helper : externalHelpers) {
|
for (String helper : externalHelpers) {
|
||||||
try {
|
try {
|
||||||
rt.exec(helper + " " + f.getAbsolutePath());
|
rt.exec(helper + " " + f.getAbsolutePath());
|
||||||
|
@ -115,9 +114,9 @@ public class DesktopIntegration {
|
||||||
Alert info = new AutosizeAlert(Alert.AlertType.ERROR);
|
Alert info = new AutosizeAlert(Alert.AlertType.ERROR);
|
||||||
info.setTitle("Open file");
|
info.setTitle("Open file");
|
||||||
info.setContentText("Couldn't open file");
|
info.setContentText("Couldn't open file");
|
||||||
BorderPane pane = new BorderPane();
|
var pane = new BorderPane();
|
||||||
pane.setTop(new Label());
|
pane.setTop(new Label());
|
||||||
TextField urlField = new TextField(f.toString());
|
var urlField = new TextField(f.toString());
|
||||||
urlField.setPadding(new Insets(10));
|
urlField.setPadding(new Insets(10));
|
||||||
urlField.setEditable(false);
|
urlField.setEditable(false);
|
||||||
pane.setCenter(urlField);
|
pane.setCenter(urlField);
|
||||||
|
@ -189,7 +188,7 @@ public class DesktopIntegration {
|
||||||
if (tray == null) {
|
if (tray == null) {
|
||||||
String title = CamrecApplication.title;
|
String title = CamrecApplication.title;
|
||||||
tray = SystemTray.getSystemTray();
|
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);
|
PopupMenu menu = createTrayContextMenu(stage);
|
||||||
trayIcon = new TrayIcon(image, title, menu);
|
trayIcon = new TrayIcon(image, title, menu);
|
||||||
|
@ -217,12 +216,12 @@ public class DesktopIntegration {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static PopupMenu createTrayContextMenu(Stage stage) {
|
private static PopupMenu createTrayContextMenu(Stage stage) {
|
||||||
PopupMenu menu = new PopupMenu();
|
var menu = new PopupMenu();
|
||||||
MenuItem show = new MenuItem("Show");
|
var show = new MenuItem("Show");
|
||||||
show.addActionListener(evt -> restoreStage(stage));
|
show.addActionListener(evt -> restoreStage(stage));
|
||||||
menu.add(show);
|
menu.add(show);
|
||||||
menu.addSeparator();
|
menu.addSeparator();
|
||||||
MenuItem pauseRecording = new MenuItem("Pause recording");
|
var pauseRecording = new MenuItem("Pause recording");
|
||||||
pauseRecording.addActionListener(evt -> {
|
pauseRecording.addActionListener(evt -> {
|
||||||
try {
|
try {
|
||||||
recorder.pause();
|
recorder.pause();
|
||||||
|
@ -231,7 +230,7 @@ public class DesktopIntegration {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
menu.add(pauseRecording);
|
menu.add(pauseRecording);
|
||||||
MenuItem resumeRecording = new MenuItem("Resume recording");
|
var resumeRecording = new MenuItem("Resume recording");
|
||||||
resumeRecording.addActionListener(evt -> {
|
resumeRecording.addActionListener(evt -> {
|
||||||
try {
|
try {
|
||||||
recorder.resume();
|
recorder.resume();
|
||||||
|
@ -241,8 +240,8 @@ public class DesktopIntegration {
|
||||||
});
|
});
|
||||||
menu.add(resumeRecording);
|
menu.add(resumeRecording);
|
||||||
menu.addSeparator();
|
menu.addSeparator();
|
||||||
MenuItem exit = new MenuItem("Exit");
|
var exit = new MenuItem("Exit");
|
||||||
exit.addActionListener(evt -> exit(stage));
|
exit.addActionListener(evt -> exit());
|
||||||
menu.add(exit);
|
menu.add(exit);
|
||||||
return menu;
|
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"));
|
EventBusHolder.BUS.post(Map.of("event", "shutdown"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,6 @@ import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import ctbrec.Config;
|
import ctbrec.Config;
|
||||||
import ctbrec.OS;
|
import ctbrec.OS;
|
||||||
import ctbrec.Settings.ProxyType;
|
|
||||||
import ctbrec.io.StreamRedirector;
|
import ctbrec.io.StreamRedirector;
|
||||||
|
|
||||||
public class ExternalBrowser implements AutoCloseable {
|
public class ExternalBrowser implements AutoCloseable {
|
||||||
|
@ -50,7 +49,7 @@ public class ExternalBrowser implements AutoCloseable {
|
||||||
|
|
||||||
addProxyConfig(jsonConfig.getJSONObject("config"));
|
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());
|
String[] cmdline = OS.getBrowserCommand(configDir.getCanonicalPath());
|
||||||
Process p = new ProcessBuilder(cmdline).start();
|
Process p = new ProcessBuilder(cmdline).start();
|
||||||
if (LOG.isTraceEnabled()) {
|
if (LOG.isTraceEnabled()) {
|
||||||
|
@ -91,7 +90,7 @@ public class ExternalBrowser implements AutoCloseable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void connectToRemoteControlSocket() throws IOException {
|
private void connectToRemoteControlSocket() throws IOException {
|
||||||
for (int i = 0; i < 20; i++) {
|
for (var i = 0; i < 20; i++) {
|
||||||
try {
|
try {
|
||||||
socket = new Socket("localhost", 3202);
|
socket = new Socket("localhost", 3202);
|
||||||
in = socket.getInputStream();
|
in = socket.getInputStream();
|
||||||
|
@ -117,7 +116,7 @@ public class ExternalBrowser implements AutoCloseable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void executeJavaScript(String javaScript) throws IOException {
|
public void executeJavaScript(String javaScript) throws IOException {
|
||||||
JSONObject script = new JSONObject();
|
var script = new JSONObject();
|
||||||
script.put("execute", javaScript);
|
script.put("execute", javaScript);
|
||||||
out.write(script.toString().getBytes(UTF_8));
|
out.write(script.toString().getBytes(UTF_8));
|
||||||
out.write('\n');
|
out.write('\n');
|
||||||
|
@ -138,7 +137,7 @@ public class ExternalBrowser implements AutoCloseable {
|
||||||
|
|
||||||
private void readBrowserOutput() {
|
private void readBrowserOutput() {
|
||||||
LOG.debug("Browser output reader started");
|
LOG.debug("Browser output reader started");
|
||||||
try (BufferedReader br = new BufferedReader(new InputStreamReader(in))) {
|
try (var br = new BufferedReader(new InputStreamReader(in))) {
|
||||||
String line;
|
String line;
|
||||||
synchronized (browserReadyLock) {
|
synchronized (browserReadyLock) {
|
||||||
browserReady = true;
|
browserReady = true;
|
||||||
|
@ -164,10 +163,10 @@ public class ExternalBrowser implements AutoCloseable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addProxyConfig(JSONObject jsonConfig) {
|
private void addProxyConfig(JSONObject jsonConfig) {
|
||||||
ProxyType proxyType = Config.getInstance().getSettings().proxyType;
|
var proxyType = Config.getInstance().getSettings().proxyType;
|
||||||
switch (proxyType) {
|
switch (proxyType) {
|
||||||
case HTTP:
|
case HTTP:
|
||||||
JSONObject proxy = new JSONObject();
|
var proxy = new JSONObject();
|
||||||
proxy.put("address",
|
proxy.put("address",
|
||||||
"http=" + Config.getInstance().getSettings().proxyHost + ':' + Config.getInstance().getSettings().proxyPort
|
"http=" + Config.getInstance().getSettings().proxyHost + ':' + Config.getInstance().getSettings().proxyPort
|
||||||
+ ";https=" + Config.getInstance().getSettings().proxyHost + ':' + Config.getInstance().getSettings().proxyPort);
|
+ ";https=" + Config.getInstance().getSettings().proxyHost + ':' + Config.getInstance().getSettings().proxyPort);
|
||||||
|
|
|
@ -12,7 +12,6 @@ import org.slf4j.LoggerFactory;
|
||||||
import ctbrec.io.HttpClient;
|
import ctbrec.io.HttpClient;
|
||||||
import ctbrec.recorder.ProgressListener;
|
import ctbrec.recorder.ProgressListener;
|
||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
import okhttp3.Response;
|
|
||||||
|
|
||||||
public class FileDownload {
|
public class FileDownload {
|
||||||
|
|
||||||
|
@ -28,13 +27,13 @@ public class FileDownload {
|
||||||
|
|
||||||
public void start(URL url, File target) throws IOException {
|
public void start(URL url, File target) throws IOException {
|
||||||
LOG.trace("Downloading file {} to {}", url, target);
|
LOG.trace("Downloading file {} to {}", url, target);
|
||||||
Request request = new Request.Builder().url(url).addHeader("connection", "keep-alive").build();
|
var request = new Request.Builder().url(url).addHeader("connection", "keep-alive").build();
|
||||||
Response response = httpClient.execute(request);
|
var response = httpClient.execute(request);
|
||||||
long fileSize = Long.parseLong(response.header("Content-Length", String.valueOf(Long.MAX_VALUE)));
|
var fileSize = Long.parseLong(response.header("Content-Length", String.valueOf(Long.MAX_VALUE)));
|
||||||
InputStream in = null;
|
InputStream in = null;
|
||||||
try (FileOutputStream fos = new FileOutputStream(target)) {
|
try (var fos = new FileOutputStream(target)) {
|
||||||
in = response.body().byteStream();
|
in = response.body().byteStream();
|
||||||
byte[] b = new byte[1024 * 100];
|
var b = new byte[1024 * 100];
|
||||||
long totalBytesRead = 0;
|
long totalBytesRead = 0;
|
||||||
int length = -1;
|
int length = -1;
|
||||||
while ((length = in.read(b)) >= 0) {
|
while ((length = in.read(b)) >= 0) {
|
||||||
|
|
|
@ -23,54 +23,63 @@ public class CheckModelAccountAction {
|
||||||
|
|
||||||
private Recorder recorder;
|
private Recorder recorder;
|
||||||
|
|
||||||
|
private String buttonText;
|
||||||
|
|
||||||
public CheckModelAccountAction(Button b, Recorder recorder) {
|
public CheckModelAccountAction(Button b, Recorder recorder) {
|
||||||
this.b = b;
|
this.b = b;
|
||||||
this.recorder = recorder;
|
this.recorder = recorder;
|
||||||
|
buttonText = b.getText();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void execute(Predicate<Model> filter) {
|
public void execute(Predicate<Model> filter) {
|
||||||
String buttonText = b.getText();
|
|
||||||
b.setDisable(true);
|
b.setDisable(true);
|
||||||
Runnable checker = (() -> {
|
Runnable checker = (() -> {
|
||||||
List<Model> deletedAccounts = new ArrayList<>();
|
List<Model> deletedAccounts = new ArrayList<>();
|
||||||
try {
|
try {
|
||||||
List<Model> models = recorder.getModels().stream() //
|
checkModelAccounts(filter, deletedAccounts);
|
||||||
.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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} finally {
|
} finally {
|
||||||
Platform.runLater(() -> {
|
showResult(deletedAccounts);
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
GlobalThreadPool.submit(checker);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import java.util.function.Consumer;
|
||||||
|
|
||||||
import ctbrec.Config;
|
import ctbrec.Config;
|
||||||
import ctbrec.Model;
|
import ctbrec.Model;
|
||||||
import ctbrec.Settings;
|
|
||||||
import ctbrec.recorder.Recorder;
|
import ctbrec.recorder.Recorder;
|
||||||
import ctbrec.ui.JavaFxModel;
|
import ctbrec.ui.JavaFxModel;
|
||||||
import ctbrec.ui.controls.Dialogs;
|
import ctbrec.ui.controls.Dialogs;
|
||||||
|
@ -29,8 +28,8 @@ public class IgnoreModelsAction {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void execute(Consumer<Model> callback) {
|
public void execute(Consumer<Model> callback) {
|
||||||
Settings settings = Config.getInstance().getSettings();
|
var settings = Config.getInstance().getSettings();
|
||||||
boolean confirmed = true;
|
var confirmed = true;
|
||||||
if (settings.confirmationForDangerousActions) {
|
if (settings.confirmationForDangerousActions) {
|
||||||
int n = selectedModels.size();
|
int n = selectedModels.size();
|
||||||
String plural = n > 1 ? "s" : "";
|
String plural = n > 1 ? "s" : "";
|
||||||
|
@ -39,7 +38,7 @@ public class IgnoreModelsAction {
|
||||||
}
|
}
|
||||||
if (confirmed) {
|
if (confirmed) {
|
||||||
for (Model model : selectedModels) {
|
for (Model model : selectedModels) {
|
||||||
Model modelToIgnore = unwrap(model);
|
var modelToIgnore = unwrap(model);
|
||||||
settings.ignoredModels.add(modelToIgnore.getUrl());
|
settings.ignoredModels.add(modelToIgnore.getUrl());
|
||||||
}
|
}
|
||||||
if (withRemoveDialog) {
|
if (withRemoveDialog) {
|
||||||
|
|
|
@ -24,7 +24,7 @@ public class OpenRecordingsDir {
|
||||||
|
|
||||||
public void execute() {
|
public void execute() {
|
||||||
source.setCursor(Cursor.WAIT);
|
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);
|
final File dir = getModelDirectory(fileForRecording);
|
||||||
if (dir.exists()) {
|
if (dir.exists()) {
|
||||||
GlobalThreadPool.submit(() -> DesktopIntegration.open(dir));
|
GlobalThreadPool.submit(() -> DesktopIntegration.open(dir));
|
||||||
|
@ -35,7 +35,7 @@ public class OpenRecordingsDir {
|
||||||
}
|
}
|
||||||
|
|
||||||
private File getModelDirectory(File fileForRecording) {
|
private File getModelDirectory(File fileForRecording) {
|
||||||
File dir = fileForRecording.getParentFile();
|
var dir = fileForRecording.getParentFile();
|
||||||
if (Config.getInstance().getSettings().recordingsDirStructure == DirectoryStructure.ONE_PER_RECORDING) {
|
if (Config.getInstance().getSettings().recordingsDirStructure == DirectoryStructure.ONE_PER_RECORDING) {
|
||||||
dir = dir.getParentFile();
|
dir = dir.getParentFile();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package ctbrec.ui.action;
|
||||||
|
|
||||||
import ctbrec.Config;
|
import ctbrec.Config;
|
||||||
import ctbrec.Model;
|
import ctbrec.Model;
|
||||||
import ctbrec.ui.SiteUI;
|
|
||||||
import ctbrec.ui.SiteUiFactory;
|
import ctbrec.ui.SiteUiFactory;
|
||||||
import ctbrec.ui.controls.Toast;
|
import ctbrec.ui.controls.Toast;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
|
@ -21,8 +20,8 @@ public class PlayAction {
|
||||||
|
|
||||||
public void execute() {
|
public void execute() {
|
||||||
source.setCursor(Cursor.WAIT);
|
source.setCursor(Cursor.WAIT);
|
||||||
Thread t = new Thread(() -> {
|
var t = new Thread(() -> {
|
||||||
SiteUI siteUI = SiteUiFactory.getUi(selectedModel.getSite());
|
var siteUI = SiteUiFactory.getUi(selectedModel.getSite());
|
||||||
boolean started = siteUI.play(selectedModel);
|
boolean started = siteUI.play(selectedModel);
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
if (started && Config.getInstance().getSettings().showPlayerStarting) {
|
if (started && Config.getInstance().getSettings().showPlayerStarting) {
|
||||||
|
|
|
@ -27,7 +27,7 @@ public class RemoveTimeLimitAction {
|
||||||
|
|
||||||
public CompletableFuture<Boolean> execute() {
|
public CompletableFuture<Boolean> execute() {
|
||||||
source.setCursor(Cursor.WAIT);
|
source.setCursor(Cursor.WAIT);
|
||||||
Instant unlimited = Instant.ofEpochMilli(Model.RECORD_INDEFINITELY);
|
var unlimited = Instant.ofEpochMilli(Model.RECORD_INDEFINITELY);
|
||||||
return CompletableFuture.supplyAsync(() -> {
|
return CompletableFuture.supplyAsync(() -> {
|
||||||
try {
|
try {
|
||||||
selectedModel.setRecordUntil(unlimited);
|
selectedModel.setRecordUntil(unlimited);
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
package ctbrec.ui.action;
|
package ctbrec.ui.action;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import ctbrec.Model;
|
import ctbrec.Model;
|
||||||
import ctbrec.recorder.Recorder;
|
import ctbrec.recorder.Recorder;
|
||||||
import ctbrec.ui.controls.Dialogs;
|
import ctbrec.ui.controls.Dialogs;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class StartRecordingAction extends ModelMassEditAction {
|
public class StartRecordingAction extends ModelMassEditAction {
|
||||||
|
|
||||||
public StartRecordingAction(Node source, List<? extends Model> models, Recorder recorder) {
|
public StartRecordingAction(Node source, List<? extends Model> models, Recorder recorder) {
|
||||||
super(source, models);
|
super(source, models);
|
||||||
action = (m) -> {
|
action = m -> {
|
||||||
try {
|
try {
|
||||||
recorder.addModel(m);
|
recorder.addModel(m);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
|
@ -11,8 +11,6 @@ import ctbrec.ui.AutosizeAlert;
|
||||||
import javafx.beans.property.SimpleStringProperty;
|
import javafx.beans.property.SimpleStringProperty;
|
||||||
import javafx.beans.property.StringProperty;
|
import javafx.beans.property.StringProperty;
|
||||||
import javafx.beans.value.ChangeListener;
|
import javafx.beans.value.ChangeListener;
|
||||||
import javafx.geometry.Point2D;
|
|
||||||
import javafx.scene.Node;
|
|
||||||
import javafx.scene.control.Alert;
|
import javafx.scene.control.Alert;
|
||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.Button;
|
||||||
import javafx.scene.control.TextField;
|
import javafx.scene.control.TextField;
|
||||||
|
@ -36,7 +34,7 @@ public abstract class AbstractFileSelectionBox extends HBox {
|
||||||
protected boolean allowEmptyValue = false;
|
protected boolean allowEmptyValue = false;
|
||||||
private Tooltip validationError = new Tooltip();
|
private Tooltip validationError = new Tooltip();
|
||||||
|
|
||||||
public AbstractFileSelectionBox() {
|
protected AbstractFileSelectionBox() {
|
||||||
super(5);
|
super(5);
|
||||||
fileInput = new TextField();
|
fileInput = new TextField();
|
||||||
fileInput.textProperty().addListener(textListener());
|
fileInput.textProperty().addListener(textListener());
|
||||||
|
@ -45,7 +43,7 @@ public abstract class AbstractFileSelectionBox extends HBox {
|
||||||
validationError.hide();
|
validationError.hide();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Node browse = createBrowseButton();
|
var browse = createBrowseButton();
|
||||||
browse.disableProperty().bind(disableProperty());
|
browse.disableProperty().bind(disableProperty());
|
||||||
fileInput.disableProperty().bind(disableProperty());
|
fileInput.disableProperty().bind(disableProperty());
|
||||||
fileInput.textProperty().bindBidirectional(fileProperty);
|
fileInput.textProperty().bindBidirectional(fileProperty);
|
||||||
|
@ -63,14 +61,14 @@ public abstract class AbstractFileSelectionBox extends HBox {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public AbstractFileSelectionBox(String initialValue) {
|
protected AbstractFileSelectionBox(String initialValue) {
|
||||||
this();
|
this();
|
||||||
fileInput.setText(initialValue);
|
fileInput.setText(initialValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ChangeListener<? super String> textListener() {
|
private ChangeListener<? super String> textListener() {
|
||||||
return (obs, o, n) -> {
|
return (obs, o, n) -> {
|
||||||
String input = fileInput.getText();
|
var input = fileInput.getText();
|
||||||
if (StringUtil.isBlank(input)) {
|
if (StringUtil.isBlank(input)) {
|
||||||
if (allowEmptyValue) {
|
if (allowEmptyValue) {
|
||||||
fileProperty.set("");
|
fileProperty.set("");
|
||||||
|
@ -78,19 +76,19 @@ public abstract class AbstractFileSelectionBox extends HBox {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
File program = new File(input);
|
var program = new File(input);
|
||||||
setFile(program);
|
setFile(program);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setFile(File file) {
|
protected void setFile(File file) {
|
||||||
String msg = validate(file);
|
var msg = validate(file);
|
||||||
if (msg != null) {
|
if (msg != null) {
|
||||||
fileInput.setBorder(new Border(new BorderStroke(Color.RED, BorderStrokeStyle.DASHED, new CornerRadii(2), new BorderWidths(2))));
|
fileInput.setBorder(new Border(new BorderStroke(Color.RED, BorderStrokeStyle.DASHED, new CornerRadii(2), new BorderWidths(2))));
|
||||||
validationError.setText(msg);
|
validationError.setText(msg);
|
||||||
fileInput.setTooltip(validationError);
|
fileInput.setTooltip(validationError);
|
||||||
Point2D p = fileInput.localToScreen(fileInput.getTranslateY(), fileInput.getTranslateY());
|
var p = fileInput.localToScreen(fileInput.getTranslateY(), fileInput.getTranslateY());
|
||||||
if (!validationError.isShowing() && getScene() != null) {
|
if (!validationError.isShowing() && getScene() != null) {
|
||||||
validationError.show(getScene().getWindow(), p.getX(), p.getY() + fileInput.getHeight() + 4);
|
validationError.show(getScene().getWindow(), p.getX(), p.getY() + fileInput.getHeight() + 4);
|
||||||
}
|
}
|
||||||
|
@ -123,7 +121,7 @@ public abstract class AbstractFileSelectionBox extends HBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Button createBrowseButton() {
|
private Button createBrowseButton() {
|
||||||
Button button = new Button("Select");
|
var button = new Button("Select");
|
||||||
button.setOnAction(e -> choose());
|
button.setOnAction(e -> choose());
|
||||||
button.prefHeightProperty().bind(this.heightProperty());
|
button.prefHeightProperty().bind(this.heightProperty());
|
||||||
button.prefWidthProperty().set(70);
|
button.prefWidthProperty().set(70);
|
||||||
|
@ -131,14 +129,14 @@ public abstract class AbstractFileSelectionBox extends HBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void choose() {
|
protected void choose() {
|
||||||
FileChooser chooser = new FileChooser();
|
var chooser = new FileChooser();
|
||||||
File program = chooser.showOpenDialog(null);
|
var program = chooser.showOpenDialog(null);
|
||||||
if (program != null) {
|
if (program != null) {
|
||||||
try {
|
try {
|
||||||
fileInput.setText(program.getCanonicalPath());
|
fileInput.setText(program.getCanonicalPath());
|
||||||
} catch (IOException e1) {
|
} catch (IOException e1) {
|
||||||
LOG.error("Couldn't determine path", 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.setTitle("Whoopsie");
|
||||||
alert.setContentText("Couldn't determine path");
|
alert.setContentText("Couldn't determine path");
|
||||||
alert.showAndWait();
|
alert.showAndWait();
|
||||||
|
|
|
@ -19,8 +19,8 @@ public class DateTimeCellFactory<T> implements Callback<TableColumn<T, Instant>,
|
||||||
if (empty || item == null) {
|
if (empty || item == null) {
|
||||||
setText("");
|
setText("");
|
||||||
} else {
|
} else {
|
||||||
LocalDateTime dateTime = LocalDateTime.ofInstant(item, ZoneId.systemDefault());
|
var dateTime = LocalDateTime.ofInstant(item, ZoneId.systemDefault());
|
||||||
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT);
|
var formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT);
|
||||||
String formattedDateTime = formatter.format(dateTime);
|
String formattedDateTime = formatter.format(dateTime);
|
||||||
setText(item.equals(Instant.EPOCH) ? "" : formattedDateTime);
|
setText(item.equals(Instant.EPOCH) ? "" : formattedDateTime);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,14 +12,14 @@ public class DirectorySelectionBox extends AbstractFileSelectionBox {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void choose() {
|
protected void choose() {
|
||||||
DirectoryChooser chooser = new DirectoryChooser();
|
var chooser = new DirectoryChooser();
|
||||||
String preselection = Optional.ofNullable(fileProperty().get()).orElse(".");
|
var preselection = Optional.ofNullable(fileProperty().get()).orElse(".");
|
||||||
File currentDir = new File(preselection);
|
var currentDir = new File(preselection);
|
||||||
if (currentDir.exists() && currentDir.isDirectory()) {
|
if (currentDir.exists() && currentDir.isDirectory()) {
|
||||||
chooser.setInitialDirectory(currentDir);
|
chooser.setInitialDirectory(currentDir);
|
||||||
}
|
}
|
||||||
File selectedDir = chooser.showDialog(null);
|
File selectedDir = chooser.showDialog(null);
|
||||||
if(selectedDir != null) {
|
if (selectedDir != null) {
|
||||||
fileInput.setText(selectedDir.getAbsolutePath());
|
fileInput.setText(selectedDir.getAbsolutePath());
|
||||||
setFile(selectedDir);
|
setFile(selectedDir);
|
||||||
}
|
}
|
||||||
|
@ -27,12 +27,12 @@ public class DirectorySelectionBox extends AbstractFileSelectionBox {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String validate(File file) {
|
protected String validate(File file) {
|
||||||
if(isDisabled()) {
|
if (isDisabled()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
String msg = super.validate(file);
|
String msg = super.validate(file);
|
||||||
if(msg != null) {
|
if (msg != null) {
|
||||||
return msg;
|
return msg;
|
||||||
} else if (!file.isDirectory()) {
|
} else if (!file.isDirectory()) {
|
||||||
return "This is not a directory";
|
return "This is not a directory";
|
||||||
|
|
|
@ -10,9 +10,9 @@ public class FasterVerticalScrollPaneSkin extends ScrollPaneSkin {
|
||||||
super(scrollPane);
|
super(scrollPane);
|
||||||
|
|
||||||
getSkinnable().addEventFilter(ScrollEvent.SCROLL, event -> {
|
getSkinnable().addEventFilter(ScrollEvent.SCROLL, event -> {
|
||||||
double ratio = scrollPane.getViewportBounds().getHeight() / scrollPane.getContent().getBoundsInLocal().getHeight();
|
var ratio = scrollPane.getViewportBounds().getHeight() / scrollPane.getContent().getBoundsInLocal().getHeight();
|
||||||
double baseUnitIncrement = 0.15;
|
var baseUnitIncrement = 0.15;
|
||||||
double unitIncrement = baseUnitIncrement * ratio * 1.25;
|
var unitIncrement = baseUnitIncrement * ratio * 1.25;
|
||||||
getVerticalScrollBar().setUnitIncrement(unitIncrement);
|
getVerticalScrollBar().setUnitIncrement(unitIncrement);
|
||||||
|
|
||||||
if (event.getDeltaX() < 0) {
|
if (event.getDeltaX() < 0) {
|
||||||
|
|
|
@ -12,12 +12,12 @@ public class FileSelectionBox extends AbstractFileSelectionBox {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String validate(File file) {
|
protected String validate(File file) {
|
||||||
if(isDisabled()) {
|
if (isDisabled()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
String msg = super.validate(file);
|
String msg = super.validate(file);
|
||||||
if(msg != null) {
|
if (msg != null) {
|
||||||
return msg;
|
return msg;
|
||||||
} else if (!file.isFile()) {
|
} else if (!file.isFile()) {
|
||||||
return "This is not a regular file";
|
return "This is not a regular file";
|
||||||
|
|
|
@ -46,10 +46,8 @@ import javafx.beans.property.SimpleDoubleProperty;
|
||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
import javafx.event.Event;
|
import javafx.event.Event;
|
||||||
import javafx.event.EventHandler;
|
import javafx.event.EventHandler;
|
||||||
import javafx.geometry.Insets;
|
|
||||||
import javafx.geometry.Point2D;
|
import javafx.geometry.Point2D;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import javafx.scene.Scene;
|
|
||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.Button;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.input.MouseEvent;
|
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 Region frameBorder = new Region();
|
||||||
private final Button leftButton = new Button("Left");
|
private final Button leftButton = new Button("Left");
|
||||||
private final Button rightButton = new Button("Right");
|
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 Pane pagesPane = new Pane();
|
||||||
private final Rectangle pagesClipRect = new Rectangle();
|
private final Rectangle pagesClipRect = new Rectangle();
|
||||||
private final Pane titlesPane = new Pane();
|
private final Pane titlesPane = new Pane();
|
||||||
|
@ -128,11 +126,6 @@ public class Popover extends Region implements EventHandler<Event>{
|
||||||
t.consume();
|
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) {
|
@Override protected double computeMinWidth(double height) {
|
||||||
Page page = pages.isEmpty() ? null : pages.getFirst();
|
Page page = pages.isEmpty() ? null : pages.getFirst();
|
||||||
if (page != null) {
|
if (page != null) {
|
||||||
Node n = page.getPageNode();
|
var n = page.getPageNode();
|
||||||
if (n != null) {
|
if (n != null) {
|
||||||
Insets insets = getInsets();
|
var insets = getInsets();
|
||||||
return insets.getLeft() + n.minWidth(-1) + insets.getRight();
|
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) {
|
@Override protected double computeMinHeight(double width) {
|
||||||
Insets insets = getInsets();
|
var insets = getInsets();
|
||||||
return insets.getLeft() + 100 + insets.getRight();
|
return insets.getLeft() + 100 + insets.getRight();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override protected double computePrefWidth(double height) {
|
@Override protected double computePrefWidth(double height) {
|
||||||
Page page = pages.isEmpty() ? null : pages.getFirst();
|
Page page = pages.isEmpty() ? null : pages.getFirst();
|
||||||
if (page != null) {
|
if (page != null) {
|
||||||
Node n = page.getPageNode();
|
var n = page.getPageNode();
|
||||||
if (n != null) {
|
if (n != null) {
|
||||||
Insets insets = getInsets();
|
var insets = getInsets();
|
||||||
return insets.getLeft() + n.prefWidth(-1) + insets.getRight();
|
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 maxHeight = maxHeight(-1);
|
||||||
double prefHeight = popoverHeight.get();
|
double prefHeight = popoverHeight.get();
|
||||||
if (prefHeight == -1) {
|
if (prefHeight == -1) {
|
||||||
Page page = pages.getFirst();
|
var page = pages.getFirst();
|
||||||
if (page != null) {
|
if (page != null) {
|
||||||
Insets inset = getInsets();
|
var inset = getInsets();
|
||||||
if (width == -1) {
|
if (width == -1) {
|
||||||
width = prefWidth(-1);
|
width = prefWidth(-1);
|
||||||
}
|
}
|
||||||
|
@ -208,7 +201,7 @@ public class Popover extends Region implements EventHandler<Event>{
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override protected double computeMaxHeight(double width) {
|
@Override protected double computeMaxHeight(double width) {
|
||||||
Scene scene = getScene();
|
var scene = getScene();
|
||||||
if (scene != null) {
|
if (scene != null) {
|
||||||
return scene.getHeight() - 100;
|
return scene.getHeight() - 100;
|
||||||
} else {
|
} else {
|
||||||
|
@ -220,14 +213,14 @@ public class Popover extends Region implements EventHandler<Event>{
|
||||||
if (maxPopupHeight == -1) {
|
if (maxPopupHeight == -1) {
|
||||||
maxPopupHeight = (int)getScene().getHeight()-100;
|
maxPopupHeight = (int)getScene().getHeight()-100;
|
||||||
}
|
}
|
||||||
final Insets insets = getInsets();
|
final var insets = getInsets();
|
||||||
final int width = (int)getWidth();
|
final int width = (int)getWidth();
|
||||||
final int height = (int)getHeight();
|
final int height = (int)getHeight();
|
||||||
final int top = (int)insets.getTop() + 40;
|
final int top = (int)insets.getTop() + 40;
|
||||||
final int right = (int)insets.getRight();
|
final int right = (int)insets.getRight();
|
||||||
final int bottom = (int)insets.getBottom();
|
final int bottom = (int)insets.getBottom();
|
||||||
final int left = (int)insets.getLeft();
|
final int left = (int)insets.getLeft();
|
||||||
final int offset = 18;
|
final var offset = 18;
|
||||||
|
|
||||||
int pageWidth = width - left - right;
|
int pageWidth = width - left - right;
|
||||||
int pageHeight = height - top - bottom;
|
int pageHeight = height - top - bottom;
|
||||||
|
@ -238,19 +231,18 @@ public class Popover extends Region implements EventHandler<Event>{
|
||||||
pagesClipRect.setWidth(pageWidth);
|
pagesClipRect.setWidth(pageWidth);
|
||||||
pagesClipRect.setHeight(pageHeight);
|
pagesClipRect.setHeight(pageHeight);
|
||||||
|
|
||||||
int pageX = 0;
|
var pageX = 0;
|
||||||
for (Node page : pagesPane.getChildren()) {
|
for (Node page : pagesPane.getChildren()) {
|
||||||
page.resizeRelocate(pageX, 0, pageWidth, pageHeight);
|
page.resizeRelocate(pageX, 0, pageWidth, pageHeight);
|
||||||
pageX += pageWidth + PAGE_GAP;
|
pageX += pageWidth + PAGE_GAP;
|
||||||
}
|
}
|
||||||
|
|
||||||
int buttonHeight = (int)(leftButton.prefHeight(-1));
|
int buttonHeight = Math.min(30, (int) (leftButton.prefHeight(-1)));
|
||||||
if (buttonHeight < 30) buttonHeight = 30;
|
final int buttonTop = (int) ((top - buttonHeight) / 2d);
|
||||||
final int buttonTop = (int)((top-buttonHeight)/2d);
|
final int leftButtonWidth = (int) snapSizeX(leftButton.prefWidth(-1));
|
||||||
final int leftButtonWidth = (int)snapSizeX(leftButton.prefWidth(-1));
|
leftButton.resizeRelocate(left, (double)buttonTop + offset, leftButtonWidth, buttonHeight);
|
||||||
leftButton.resizeRelocate(left, buttonTop + offset,leftButtonWidth,buttonHeight);
|
final int rightButtonWidth = (int) snapSizeX(rightButton.prefWidth(-1));
|
||||||
final int rightButtonWidth = (int)snapSizeX(rightButton.prefWidth(-1));
|
rightButton.resizeRelocate(width - (double)right - rightButtonWidth, (double)buttonTop + offset, rightButtonWidth, buttonHeight);
|
||||||
rightButton.resizeRelocate(width-right-rightButtonWidth, buttonTop + offset,rightButtonWidth,buttonHeight);
|
|
||||||
|
|
||||||
if (title != null) {
|
if (title != null) {
|
||||||
double tw = title.getWidth();
|
double tw = title.getWidth();
|
||||||
|
@ -275,16 +267,16 @@ public class Popover extends Region implements EventHandler<Event>{
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void popPage() {
|
public final void popPage() {
|
||||||
Page oldPage = pages.pop();
|
var oldPage = pages.pop();
|
||||||
oldPage.handleHidden();
|
oldPage.handleHidden();
|
||||||
oldPage.setPopover(null);
|
oldPage.setPopover(null);
|
||||||
Page page = pages.getFirst();
|
var page = pages.getFirst();
|
||||||
leftButton.setVisible(page.leftButtonText() != null);
|
leftButton.setVisible(page.leftButtonText() != null);
|
||||||
leftButton.setText(page.leftButtonText());
|
leftButton.setText(page.leftButtonText());
|
||||||
rightButton.setVisible(page.rightButtonText() != null);
|
rightButton.setVisible(page.rightButtonText() != null);
|
||||||
rightButton.setText(page.rightButtonText());
|
rightButton.setText(page.rightButtonText());
|
||||||
if (pages.size() > 0) {
|
if (!pages.isEmpty()) {
|
||||||
final Insets insets = getInsets();
|
final var insets = getInsets();
|
||||||
final int width = (int)prefWidth(-1);
|
final int width = (int)prefWidth(-1);
|
||||||
final int right = (int)insets.getRight();
|
final int right = (int)insets.getRight();
|
||||||
final int left = (int)insets.getLeft();
|
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) {
|
public final void pushPage(final Page page) {
|
||||||
final Node pageNode = page.getPageNode();
|
final var pageNode = page.getPageNode();
|
||||||
pageNode.setManaged(false);
|
pageNode.setManaged(false);
|
||||||
pagesPane.getChildren().add(pageNode);
|
pagesPane.getChildren().add(pageNode);
|
||||||
final Insets insets = getInsets();
|
final var insets = getInsets();
|
||||||
final int pageWidth = (int)(prefWidth(-1) - insets.getLeft() - insets.getRight());
|
final int pageWidth = (int)(prefWidth(-1) - insets.getLeft() - insets.getRight());
|
||||||
final int newPageX = (pageWidth + PAGE_GAP) * pages.size();
|
final int newPageX = (pageWidth + PAGE_GAP) * pages.size();
|
||||||
leftButton.setVisible(page.leftButtonText() != null);
|
leftButton.setVisible(page.leftButtonText() != null);
|
||||||
|
@ -322,11 +314,11 @@ public class Popover extends Region implements EventHandler<Event>{
|
||||||
title = new Label(page.getPageTitle());
|
title = new Label(page.getPageTitle());
|
||||||
title.getStyleClass().add("popover-title");
|
title.getStyleClass().add("popover-title");
|
||||||
title.setTextAlignment(TextAlignment.CENTER);
|
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);
|
titlesPane.getChildren().add(title);
|
||||||
|
|
||||||
if (!pages.isEmpty() && isVisible()) {
|
if (!pages.isEmpty() && isVisible()) {
|
||||||
final Timeline timeline = new Timeline(
|
final var timeline = new Timeline(
|
||||||
new KeyFrame(Duration.millis(350), (ActionEvent t) -> {
|
new KeyFrame(Duration.millis(350), (ActionEvent t) -> {
|
||||||
pagesPane.setCache(false);
|
pagesPane.setCache(false);
|
||||||
resizePopoverToNewPage(pageNode);
|
resizePopoverToNewPage(pageNode);
|
||||||
|
@ -344,7 +336,7 @@ public class Popover extends Region implements EventHandler<Event>{
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resizePopoverToNewPage(final Node newPageNode) {
|
private void resizePopoverToNewPage(final Node newPageNode) {
|
||||||
final Insets insets = getInsets();
|
final var insets = getInsets();
|
||||||
final double width = prefWidth(-1);
|
final double width = prefWidth(-1);
|
||||||
final double contentWidth = width - insets.getLeft() - insets.getRight();
|
final double contentWidth = width - insets.getLeft() - insets.getRight();
|
||||||
double h = newPageNode.prefHeight(contentWidth);
|
double h = newPageNode.prefHeight(contentWidth);
|
||||||
|
@ -366,7 +358,6 @@ public class Popover extends Region implements EventHandler<Event>{
|
||||||
if (!isVisible() || fadeAnimation != null) {
|
if (!isVisible() || fadeAnimation != null) {
|
||||||
this.onHideCallback = onHideCallback;
|
this.onHideCallback = onHideCallback;
|
||||||
getScene().addEventFilter(MouseEvent.MOUSE_CLICKED, popoverHideHandler);
|
getScene().addEventFilter(MouseEvent.MOUSE_CLICKED, popoverHideHandler);
|
||||||
// getScene().addEventFilter(ScrollEvent.ANY,popoverScrollHandler);
|
|
||||||
|
|
||||||
if (fadeAnimation != null) {
|
if (fadeAnimation != null) {
|
||||||
fadeAnimation.stop();
|
fadeAnimation.stop();
|
||||||
|
@ -376,17 +367,15 @@ public class Popover extends Region implements EventHandler<Event>{
|
||||||
setVisible(true);
|
setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
FadeTransition fade = new FadeTransition(Duration.seconds(.1), this);
|
var fade = new FadeTransition(Duration.seconds(.1), this);
|
||||||
fade.setToValue(1.0);
|
fade.setToValue(1.0);
|
||||||
fade.setOnFinished((ActionEvent event) -> {
|
fade.setOnFinished((ActionEvent event) -> fadeAnimation = null);
|
||||||
fadeAnimation = null;
|
|
||||||
});
|
|
||||||
|
|
||||||
ScaleTransition scale = new ScaleTransition(Duration.seconds(.1), this);
|
var scale = new ScaleTransition(Duration.seconds(.1), this);
|
||||||
scale.setToX(1);
|
scale.setToX(1);
|
||||||
scale.setToY(1);
|
scale.setToY(1);
|
||||||
|
|
||||||
ParallelTransition tx = new ParallelTransition(fade, scale);
|
var tx = new ParallelTransition(fade, scale);
|
||||||
fadeAnimation = tx;
|
fadeAnimation = tx;
|
||||||
tx.play();
|
tx.play();
|
||||||
}
|
}
|
||||||
|
@ -395,26 +384,24 @@ public class Popover extends Region implements EventHandler<Event>{
|
||||||
public void hide(){
|
public void hide(){
|
||||||
if (isVisible() || fadeAnimation != null) {
|
if (isVisible() || fadeAnimation != null) {
|
||||||
getScene().removeEventFilter(MouseEvent.MOUSE_CLICKED, popoverHideHandler);
|
getScene().removeEventFilter(MouseEvent.MOUSE_CLICKED, popoverHideHandler);
|
||||||
// getScene().removeEventFilter(ScrollEvent.ANY,popoverScrollHandler);
|
|
||||||
|
|
||||||
if (fadeAnimation != null) {
|
if (fadeAnimation != null) {
|
||||||
fadeAnimation.stop();
|
fadeAnimation.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
FadeTransition fade = new FadeTransition(Duration.seconds(.1), this);
|
var fade = new FadeTransition(Duration.seconds(.1), this);
|
||||||
fade.setToValue(0);
|
fade.setToValue(0);
|
||||||
fade.setOnFinished((ActionEvent event) -> {
|
fade.setOnFinished((ActionEvent event) -> {
|
||||||
fadeAnimation = null;
|
fadeAnimation = null;
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
//clearPages();
|
|
||||||
if (onHideCallback != null) onHideCallback.run();
|
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.setToX(.8);
|
||||||
scale.setToY(.8);
|
scale.setToY(.8);
|
||||||
|
|
||||||
ParallelTransition tx = new ParallelTransition(fade, scale);
|
var tx = new ParallelTransition(fade, scale);
|
||||||
fadeAnimation = tx;
|
fadeAnimation = tx;
|
||||||
tx.play();
|
tx.play();
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ public class PopoverTreeList<T> extends ListView<T> implements Callback<ListView
|
||||||
return new TreeItemListCell();
|
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 class TreeItemListCell extends ListCell<T> implements EventHandler<MouseEvent> {
|
||||||
private TreeItemListCell() {
|
private TreeItemListCell() {
|
||||||
|
|
|
@ -12,12 +12,12 @@ public class ProgramSelectionBox extends FileSelectionBox {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String validate(File file) {
|
protected String validate(File file) {
|
||||||
if(isDisabled()) {
|
if (isDisabled()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
String msg = super.validate(file);
|
String msg = super.validate(file);
|
||||||
if(msg != null) {
|
if (msg != null) {
|
||||||
return msg;
|
return msg;
|
||||||
} else if (!file.canExecute()) {
|
} else if (!file.canExecute()) {
|
||||||
return "This is not an executable application";
|
return "This is not an executable application";
|
||||||
|
|
|
@ -34,4 +34,3 @@ public class RecordingIndicator extends StackPane {
|
||||||
icon.setImage(img);
|
icon.setImage(img);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,10 +44,10 @@ import javafx.scene.layout.Region;
|
||||||
* Search field with styling and a clear button
|
* Search field with styling and a clear button
|
||||||
*/
|
*/
|
||||||
public class SearchBox extends TextField implements ChangeListener<String>{
|
public class SearchBox extends TextField implements ChangeListener<String>{
|
||||||
|
private static final int PREF_HEIGHT = 26;
|
||||||
private final Button clearButton = new Button();
|
private final Button clearButton = new Button();
|
||||||
private final Region innerBackground = new Region();
|
private final Region innerBackground = new Region();
|
||||||
private final Region icon = new Region();
|
private final Region icon = new Region();
|
||||||
private final int prefHeight = 26;
|
|
||||||
|
|
||||||
public SearchBox() {
|
public SearchBox() {
|
||||||
getStyleClass().addAll("search-box");
|
getStyleClass().addAll("search-box");
|
||||||
|
@ -55,7 +55,7 @@ public class SearchBox extends TextField implements ChangeListener<String>{
|
||||||
innerBackground.getStyleClass().setAll("search-box-inner");
|
innerBackground.getStyleClass().setAll("search-box-inner");
|
||||||
setPromptText("Search");
|
setPromptText("Search");
|
||||||
textProperty().addListener(this);
|
textProperty().addListener(this);
|
||||||
setPrefHeight(prefHeight);
|
setPrefHeight(PREF_HEIGHT);
|
||||||
clearButton.getStyleClass().setAll("search-clear-button");
|
clearButton.getStyleClass().setAll("search-clear-button");
|
||||||
clearButton.setCursor(Cursor.DEFAULT);
|
clearButton.setCursor(Cursor.DEFAULT);
|
||||||
clearButton.setOnMouseClicked((MouseEvent t) -> {
|
clearButton.setOnMouseClicked((MouseEvent t) -> {
|
||||||
|
@ -91,10 +91,10 @@ public class SearchBox extends TextField implements ChangeListener<String>{
|
||||||
innerBackground.resize(getWidth(), getHeight());
|
innerBackground.resize(getWidth(), getHeight());
|
||||||
icon.setLayoutX(0);
|
icon.setLayoutX(0);
|
||||||
icon.setLayoutY(0);
|
icon.setLayoutY(0);
|
||||||
icon.resize(35,prefHeight);
|
icon.resize(35,PREF_HEIGHT);
|
||||||
clearButton.setLayoutX(getWidth() - prefHeight);
|
clearButton.setLayoutX(getWidth() - PREF_HEIGHT);
|
||||||
clearButton.setLayoutY(0);
|
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) {
|
@Override public void changed(ObservableValue<? extends String> ov, String oldValue, String newValue) {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package ctbrec.ui.controls.autocomplete;
|
package ctbrec.ui.controls.autocomplete;
|
||||||
|
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
|
@ -36,18 +35,18 @@ public class AutoFillTextField extends TextField {
|
||||||
|
|
||||||
private void autocomplete(boolean fulltextSearch) {
|
private void autocomplete(boolean fulltextSearch) {
|
||||||
String oldtext = getOldText();
|
String oldtext = getOldText();
|
||||||
if(oldtext.isEmpty()) {
|
if (oldtext.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<String> match = null;
|
Optional<String> match;
|
||||||
if(fulltextSearch) {
|
if (fulltextSearch) {
|
||||||
match = suggester.fulltext(oldtext);
|
match = suggester.fulltext(oldtext);
|
||||||
} else {
|
} else {
|
||||||
match = suggester.startsWith(oldtext);
|
match = suggester.startsWith(oldtext);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(match.isPresent()) {
|
if (match.isPresent()) {
|
||||||
setText(match.get());
|
setText(match.get());
|
||||||
int pos = oldtext.length();
|
int pos = oldtext.length();
|
||||||
positionCaret(pos);
|
positionCaret(pos);
|
||||||
|
@ -56,7 +55,7 @@ public class AutoFillTextField extends TextField {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getOldText() {
|
private String getOldText() {
|
||||||
if(getSelection().getLength() > 0) {
|
if (getSelection().getLength() > 0) {
|
||||||
return getText().substring(0, getSelection().getStart());
|
return getText().substring(0, getSelection().getStart());
|
||||||
} else {
|
} else {
|
||||||
return getText();
|
return getText();
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
package ctbrec.ui.controls.autocomplete;
|
|
||||||
|
|
||||||
public class Suggestion {
|
|
||||||
|
|
||||||
}
|
|
|
@ -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
|
* The mouse position on track with 0.0 being beginning of track and 1.0 being the end
|
||||||
*/
|
*/
|
||||||
public void lowThumbDragged(double position) {
|
public void lowThumbDragged(double position) {
|
||||||
T newPosition = getNewPosition(position);
|
var newPosition = getNewPosition(position);
|
||||||
T high = getHigh();
|
var high = getHigh();
|
||||||
if (newPosition.doubleValue() >= high.doubleValue()) {
|
if (newPosition.doubleValue() >= high.doubleValue()) {
|
||||||
newPosition = getLow();
|
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
|
* The mouse position on track with 0.0 being beginning of track and 1.0 being the end
|
||||||
*/
|
*/
|
||||||
public void highThumbDragged(double position) {
|
public void highThumbDragged(double position) {
|
||||||
T newPosition = getNewPosition(position);
|
var newPosition = getNewPosition(position);
|
||||||
T low = getLow();
|
var low = getLow();
|
||||||
if (newPosition.doubleValue() <= low.doubleValue()) {
|
if (newPosition.doubleValue() <= low.doubleValue()) {
|
||||||
newPosition = getHigh();
|
newPosition = getHigh();
|
||||||
}
|
}
|
||||||
|
@ -57,9 +57,9 @@ public class RangeSliderBehavior<T extends Number> extends BehaviorBase<RangeSli
|
||||||
}
|
}
|
||||||
|
|
||||||
public void moveClosestThumbTo(double positionPercentage) {
|
public void moveClosestThumbTo(double positionPercentage) {
|
||||||
T newPosition = getNewPosition(positionPercentage);
|
var newPosition = getNewPosition(positionPercentage);
|
||||||
T low = getLow();
|
var low = getLow();
|
||||||
T high = getHigh();
|
var high = getHigh();
|
||||||
double distToLow = Math.abs(low.doubleValue() - newPosition.doubleValue());
|
double distToLow = Math.abs(low.doubleValue() - newPosition.doubleValue());
|
||||||
double distToHigh = Math.abs(high.doubleValue() - newPosition.doubleValue());
|
double distToHigh = Math.abs(high.doubleValue() - newPosition.doubleValue());
|
||||||
if (distToLow < distToHigh) {
|
if (distToLow < distToHigh) {
|
||||||
|
|
|
@ -122,39 +122,39 @@ public class RangeSliderSkin extends SkinBase<RangeSlider<?>> {
|
||||||
thumbRange.high.resize(thumbWidth, thumbHeight);
|
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 radius = track.getBackground().getFills().isEmpty() ? 0 : track.getBackground().getFills().get(0).getRadii().getTopLeftHorizontalRadius();
|
||||||
double trackHeight = 5;// track.prefHeight(-1);
|
double trackRadius = track.getBackground() == null ? 0 : radius;
|
||||||
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
|
|
||||||
|
|
||||||
trackLength = w - thumbWidth;
|
double tickLineHeight = (showTickMarks) ? tickLine.prefHeight(-1) : 0;
|
||||||
trackStart = x + (thumbWidth / 2);
|
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));
|
trackLength = w - thumbWidth;
|
||||||
lowThumbPos = (int) (startY + ((trackAreaHeight - thumbHeight) / 2));
|
trackStart = x + (thumbWidth / 2);
|
||||||
|
|
||||||
// layout track
|
double trackTop = (int) (startY + ((trackAreaHeight - trackHeight) / 2));
|
||||||
track.resizeRelocate(trackStart - trackRadius, trackTop, trackLength + trackRadius + trackRadius, trackHeight);
|
lowThumbPos = (int) (startY + ((trackAreaHeight - thumbHeight) / 2));
|
||||||
|
|
||||||
positionThumbs();
|
// layout track
|
||||||
|
track.resizeRelocate(trackStart - trackRadius, trackTop, trackLength + trackRadius + trackRadius, trackHeight);
|
||||||
|
|
||||||
if (showTickMarks) {
|
positionThumbs();
|
||||||
tickLine.setLayoutX(trackStart);
|
|
||||||
tickLine.setLayoutY(trackTop + trackHeight + TRACK_TO_TICK_GAP);
|
if (showTickMarks) {
|
||||||
tickLine.resize(trackLength, tickLineHeight);
|
tickLine.setLayoutX(trackStart);
|
||||||
tickLine.requestAxisLayout();
|
tickLine.setLayoutY(trackTop + trackHeight + TRACK_TO_TICK_GAP);
|
||||||
} else {
|
tickLine.resize(trackLength, tickLineHeight);
|
||||||
if (tickLine != null) {
|
tickLine.requestAxisLayout();
|
||||||
tickLine.resize(0, 0);
|
} else {
|
||||||
tickLine.requestAxisLayout();
|
if (tickLine != null) {
|
||||||
}
|
tickLine.resize(0, 0);
|
||||||
tickLine = null;
|
tickLine.requestAxisLayout();
|
||||||
}
|
}
|
||||||
|
tickLine = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void positionThumbs() {
|
private void positionThumbs() {
|
||||||
|
|
|
@ -23,13 +23,13 @@ public class PlaySound extends Action {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void accept(Event evt) {
|
public void accept(Event evt) {
|
||||||
AudioClip clip = new AudioClip(url.toString());
|
var clip = new AudioClip(url.toString());
|
||||||
clip.play();
|
clip.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void configure(ActionConfiguration config) throws Exception {
|
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();
|
url = file.toURI().toURL();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ public class ShowNotification extends Action {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void accept(Event evt) {
|
public void accept(Event evt) {
|
||||||
String header = evt.getType().toString();
|
var header = evt.getType().toString();
|
||||||
String msg;
|
String msg;
|
||||||
switch(evt.getType()) {
|
switch(evt.getType()) {
|
||||||
case MODEL_STATUS_CHANGED:
|
case MODEL_STATUS_CHANGED:
|
||||||
|
@ -25,7 +25,7 @@ public class ShowNotification extends Action {
|
||||||
if (modelEvent.getOldState() == Model.State.UNKNOWN) {
|
if (modelEvent.getOldState() == Model.State.UNKNOWN) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Model m = modelEvent.getModel();
|
var m = modelEvent.getModel();
|
||||||
msg = m.getDisplayName() + " is now " + modelEvent.getNewState().toString();
|
msg = m.getDisplayName() + " is now " + modelEvent.getNewState().toString();
|
||||||
break;
|
break;
|
||||||
case RECORDING_STATUS_CHANGED:
|
case RECORDING_STATUS_CHANGED:
|
||||||
|
@ -41,5 +41,6 @@ public class ShowNotification extends Action {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void configure(ActionConfiguration config) throws Exception {
|
public void configure(ActionConfiguration config) throws Exception {
|
||||||
|
// nothing to do here
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@ import javafx.scene.control.ScrollPane;
|
||||||
import javafx.scene.control.Tab;
|
import javafx.scene.control.Tab;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
import okhttp3.Response;
|
|
||||||
|
|
||||||
public class NewsTab extends Tab implements TabSelectionListener {
|
public class NewsTab extends Tab implements TabSelectionListener {
|
||||||
private static final String ACCESS_TOKEN = "a2804d73a89951a22e0f8483a6fcec8943afd88b7ba17c459c095aa9e6f94fd0";
|
private static final String ACCESS_TOKEN = "a2804d73a89951a22e0f8483a6fcec8943afd88b7ba17c459c095aa9e6f94fd0";
|
||||||
|
@ -44,14 +43,14 @@ public class NewsTab extends Tab implements TabSelectionListener {
|
||||||
|
|
||||||
private void loadToots() {
|
private void loadToots() {
|
||||||
try {
|
try {
|
||||||
Request request = new Request.Builder()
|
var request = new Request.Builder()
|
||||||
.url(URL)
|
.url(URL)
|
||||||
.header("Authorization", "Bearer " + ACCESS_TOKEN)
|
.header("Authorization", "Bearer " + ACCESS_TOKEN)
|
||||||
.header(USER_AGENT, "ctbrec " + CamrecApplication.getVersion().toString())
|
.header(USER_AGENT, "ctbrec " + CamrecApplication.getVersion().toString())
|
||||||
.build();
|
.build();
|
||||||
try (Response response = CamrecApplication.httpClient.execute(request)) {
|
try (var response = CamrecApplication.httpClient.execute(request)) {
|
||||||
if (response.isSuccessful()) {
|
if (response.isSuccessful()) {
|
||||||
String body = response.body().string();
|
var body = response.body().string();
|
||||||
if (body.startsWith("[")) {
|
if (body.startsWith("[")) {
|
||||||
onSuccess(body);
|
onSuccess(body);
|
||||||
} else if (body.startsWith("{")) {
|
} else if (body.startsWith("{")) {
|
||||||
|
@ -69,7 +68,7 @@ public class NewsTab extends Tab implements TabSelectionListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onError(String body) throws IOException {
|
private void onError(String body) throws IOException {
|
||||||
JSONObject json = new JSONObject(body);
|
var json = new JSONObject(body);
|
||||||
if (json.has("error")) {
|
if (json.has("error")) {
|
||||||
throw new IOException("Request not successful: " + json.getString("error"));
|
throw new IOException("Request not successful: " + json.getString("error"));
|
||||||
} else {
|
} else {
|
||||||
|
@ -78,14 +77,14 @@ public class NewsTab extends Tab implements TabSelectionListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onSuccess(String body) throws IOException {
|
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);
|
JsonAdapter<Status[]> statusListAdapter = moshi.adapter(Status[].class);
|
||||||
Status[] statusArray = statusListAdapter.fromJson(body);
|
Status[] statusArray = statusListAdapter.fromJson(body);
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
layout.getChildren().clear();
|
layout.getChildren().clear();
|
||||||
for (Status status : statusArray) {
|
for (Status status : statusArray) {
|
||||||
if (status.getInReplyToId() == null && !Objects.equals("direct", status.getVisibility())) {
|
if (status.getInReplyToId() == null && !Objects.equals("direct", status.getVisibility())) {
|
||||||
StatusPane stp = new StatusPane(status);
|
var stp = new StatusPane(status);
|
||||||
layout.getChildren().add(stp);
|
layout.getChildren().add(stp);
|
||||||
VBox.setMargin(stp, new Insets(10));
|
VBox.setMargin(stp, new Insets(10));
|
||||||
}
|
}
|
||||||
|
|
|
@ -272,8 +272,8 @@ public class Status {
|
||||||
|
|
||||||
public ZonedDateTime getCreationTime() {
|
public ZonedDateTime getCreationTime() {
|
||||||
String timestamp = getCreatedAt();
|
String timestamp = getCreatedAt();
|
||||||
Instant instant = Instant.parse(timestamp);
|
var instant = Instant.parse(timestamp);
|
||||||
ZonedDateTime time = ZonedDateTime.ofInstant(instant, ZoneId.systemDefault());
|
var time = ZonedDateTime.ofInstant(instant, ZoneId.systemDefault());
|
||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ public class StatusPane extends StackPane {
|
||||||
|
|
||||||
ZonedDateTime createdAt = status.getCreationTime();
|
ZonedDateTime createdAt = status.getCreationTime();
|
||||||
String creationTime = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT, FormatStyle.SHORT).format(createdAt);
|
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.setStyle("-fx-background-color: -fx-base");
|
||||||
time.setOpacity(.7);
|
time.setOpacity(.7);
|
||||||
time.setPadding(new Insets(3));
|
time.setPadding(new Insets(3));
|
||||||
|
@ -45,7 +45,7 @@ public class StatusPane extends StackPane {
|
||||||
getChildren().add(time);
|
getChildren().add(time);
|
||||||
StackPane.setMargin(time, new Insets(5, 5, 5, 10));
|
StackPane.setMargin(time, new Insets(5, 5, 5, 10));
|
||||||
StackPane.setAlignment(time, Pos.BOTTOM_LEFT);
|
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.heightProperty().bind(time.heightProperty());
|
||||||
clip.widthProperty().bind(time.widthProperty());
|
clip.widthProperty().bind(time.widthProperty());
|
||||||
clip.setArcHeight(5);
|
clip.setArcHeight(5);
|
||||||
|
@ -53,7 +53,7 @@ public class StatusPane extends StackPane {
|
||||||
time.setClip(clip);
|
time.setClip(clip);
|
||||||
|
|
||||||
reply = new Button("Reply");
|
reply = new Button("Reply");
|
||||||
reply.setOnAction((evt) -> DesktopIntegration.open(status.getUrl()));
|
reply.setOnAction(evt -> DesktopIntegration.open(status.getUrl()));
|
||||||
getChildren().add(reply);
|
getChildren().add(reply);
|
||||||
StackPane.setMargin(reply, new Insets(5, 5, 5, 5));
|
StackPane.setMargin(reply, new Insets(5, 5, 5, 5));
|
||||||
StackPane.setAlignment(reply, Pos.BOTTOM_RIGHT);
|
StackPane.setAlignment(reply, Pos.BOTTOM_RIGHT);
|
||||||
|
@ -64,7 +64,7 @@ public class StatusPane extends StackPane {
|
||||||
ObservableList<Node> childrenUnmodifiable = content.getChildrenUnmodifiable();
|
ObservableList<Node> childrenUnmodifiable = content.getChildrenUnmodifiable();
|
||||||
for (Node node : childrenUnmodifiable) {
|
for (Node node : childrenUnmodifiable) {
|
||||||
if (node instanceof ScrollPane) {
|
if (node instanceof ScrollPane) {
|
||||||
ScrollPane scrollPane = (ScrollPane) node;
|
var scrollPane = (ScrollPane) node;
|
||||||
Set<Node> nodes = scrollPane.lookupAll(".scroll-bar");
|
Set<Node> nodes = scrollPane.lookupAll(".scroll-bar");
|
||||||
for (final Node child : nodes) {
|
for (final Node child : nodes) {
|
||||||
if (child instanceof ScrollBar) {
|
if (child instanceof ScrollBar) {
|
||||||
|
|
|
@ -47,13 +47,12 @@ public abstract class AbstractPostProcessingPaneFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
class MapPreferencesStorage implements PreferencesStorage {
|
class MapPreferencesStorage implements PreferencesStorage {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void save(Preferences preferences) throws IOException {
|
public void save(Preferences preferences) throws IOException {
|
||||||
for (Property<?> property : properties) {
|
for (Property<?> property : properties) {
|
||||||
String key = property.getName();
|
String key = property.getName();
|
||||||
Object value = preferences.getSetting(key).get().getProperty().getValue();
|
Object value = preferences.getSetting(key).get().getProperty().getValue();
|
||||||
LOG.debug("{}={}", key, value.toString());
|
LOG.debug("{}={}", key, value);
|
||||||
pp.getConfig().put(key, value.toString());
|
pp.getConfig().put(key, value.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,7 +63,7 @@ public abstract class AbstractPostProcessingPaneFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Node createGui(Setting setting) throws Exception {
|
public Node createGui(Setting setting) throws NoSuchFieldException, IllegalAccessException {
|
||||||
Property<?> prop = setting.getProperty();
|
Property<?> prop = setting.getProperty();
|
||||||
if (prop instanceof ExclusiveSelectionProperty) {
|
if (prop instanceof ExclusiveSelectionProperty) {
|
||||||
return createRadioGroup(setting);
|
return createRadioGroup(setting);
|
||||||
|
@ -86,109 +85,74 @@ public abstract class AbstractPostProcessingPaneFactory {
|
||||||
return new Label("Unsupported Type for key " + setting.getKey() + ": " + setting.getProperty());
|
return new Label("Unsupported Type for key " + setting.getKey() + ": " + setting.getProperty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private Node createRadioGroup(Setting setting) {
|
private Node createRadioGroup(Setting setting) {
|
||||||
ExclusiveSelectionProperty prop = (ExclusiveSelectionProperty) setting.getProperty();
|
ExclusiveSelectionProperty prop = (ExclusiveSelectionProperty) setting.getProperty();
|
||||||
ToggleGroup toggleGroup = new ToggleGroup();
|
var toggleGroup = new ToggleGroup();
|
||||||
RadioButton optionA = new RadioButton(prop.getOptionA());
|
var optionA = new RadioButton(prop.getOptionA());
|
||||||
optionA.setSelected(prop.getValue());
|
optionA.setSelected(prop.getValue());
|
||||||
optionA.setToggleGroup(toggleGroup);
|
optionA.setToggleGroup(toggleGroup);
|
||||||
RadioButton optionB = new RadioButton(prop.getOptionB());
|
var optionB = new RadioButton(prop.getOptionB());
|
||||||
optionB.setSelected(!optionA.isSelected());
|
optionB.setSelected(!optionA.isSelected());
|
||||||
optionB.setToggleGroup(toggleGroup);
|
optionB.setToggleGroup(toggleGroup);
|
||||||
optionA.selectedProperty().bindBidirectional(prop);
|
optionA.selectedProperty().bindBidirectional(prop);
|
||||||
HBox row = new HBox();
|
var row = new HBox();
|
||||||
row.getChildren().addAll(optionA, optionB);
|
row.getChildren().addAll(optionA, optionB);
|
||||||
HBox.setMargin(optionA, new Insets(5));
|
HBox.setMargin(optionA, new Insets(5));
|
||||||
HBox.setMargin(optionB, new Insets(5));
|
HBox.setMargin(optionB, new Insets(5));
|
||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Node createFileSelector(Setting setting) {
|
private Node createFileSelector(Setting setting) {
|
||||||
ProgramSelectionBox programSelector = new ProgramSelectionBox("");
|
var programSelector = new ProgramSelectionBox("");
|
||||||
// programSelector.fileProperty().addListener((obs, o, n) -> saveValue(() -> {
|
StringProperty property = (StringProperty) setting.getProperty();
|
||||||
// String path = n;
|
programSelector.fileProperty().bindBidirectional(property);
|
||||||
// Field field = Settings.class.getField(setting.getKey());
|
return programSelector;
|
||||||
// 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 createDirectorySelector(Setting setting) {
|
private Node createDirectorySelector(Setting setting) {
|
||||||
DirectorySelectionBox directorySelector = new DirectorySelectionBox("");
|
var directorySelector = new DirectorySelectionBox("");
|
||||||
directorySelector.prefWidth(400);
|
directorySelector.prefWidth(400);
|
||||||
// directorySelector.fileProperty().addListener((obs, o, n) -> saveValue(() -> {
|
StringProperty property = (StringProperty) setting.getProperty();
|
||||||
// String path = n;
|
directorySelector.fileProperty().bindBidirectional(property);
|
||||||
// Field field = Settings.class.getField(setting.getKey());
|
return directorySelector;
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private Node createStringProperty(Setting setting) {
|
private Node createStringProperty(Setting setting) {
|
||||||
TextField ctrl = new TextField();
|
var ctrl = new TextField();
|
||||||
ctrl.textProperty().bindBidirectional(setting.getProperty());
|
ctrl.textProperty().bindBidirectional(setting.getProperty());
|
||||||
return ctrl;
|
return ctrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private Node createIntegerProperty(Setting setting) {
|
private Node createIntegerProperty(Setting setting) {
|
||||||
TextField ctrl = new TextField();
|
var ctrl = new TextField();
|
||||||
Property<Number> prop = setting.getProperty();
|
Property<Number> prop = setting.getProperty();
|
||||||
ctrl.textProperty().bindBidirectional(prop, new NumberStringConverter());
|
ctrl.textProperty().bindBidirectional(prop, new NumberStringConverter());
|
||||||
return ctrl;
|
return ctrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private Node createLongProperty(Setting setting) {
|
private Node createLongProperty(Setting setting) {
|
||||||
TextField ctrl = new TextField();
|
var ctrl = new TextField();
|
||||||
Property<Number> prop = setting.getProperty();
|
Property<Number> prop = setting.getProperty();
|
||||||
ctrl.textProperty().bindBidirectional(prop, new NumberStringConverter());
|
ctrl.textProperty().bindBidirectional(prop, new NumberStringConverter());
|
||||||
return ctrl;
|
return ctrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Node createBooleanProperty(Setting setting) {
|
private Node createBooleanProperty(Setting setting) {
|
||||||
CheckBox ctrl = new CheckBox();
|
var ctrl = new CheckBox();
|
||||||
BooleanProperty prop = (BooleanProperty) setting.getProperty();
|
BooleanProperty prop = (BooleanProperty) setting.getProperty();
|
||||||
ctrl.selectedProperty().bindBidirectional(prop);
|
ctrl.selectedProperty().bindBidirectional(prop);
|
||||||
return ctrl;
|
return ctrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
private Node createComboBox(Setting setting) throws NoSuchFieldException, IllegalAccessException {
|
private Node createComboBox(Setting setting) {
|
||||||
ListProperty<?> listProp = (ListProperty<?>) setting.getProperty();
|
ListProperty<?> listProp = (ListProperty<?>) setting.getProperty();
|
||||||
ComboBox<Object> comboBox = new ComboBox(listProp);
|
ComboBox<Object> comboBox = new ComboBox(listProp);
|
||||||
// Field field = Settings.class.getField(setting.getKey());
|
return comboBox;
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,24 +94,24 @@ public class ActionSettingsPanel extends GridPane {
|
||||||
setVgap(10);
|
setVgap(10);
|
||||||
setPadding(new Insets(20, 10, 10, 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");
|
headline.getStyleClass().add("settings-group-label");
|
||||||
add(headline, 0, 0);
|
add(headline, 0, 0);
|
||||||
|
|
||||||
actionTable = createActionTable();
|
actionTable = createActionTable();
|
||||||
ScrollPane scrollPane = new ScrollPane(actionTable);
|
var scrollPane = new ScrollPane(actionTable);
|
||||||
scrollPane.setFitToHeight(true);
|
scrollPane.setFitToHeight(true);
|
||||||
scrollPane.setFitToWidth(true);
|
scrollPane.setFitToWidth(true);
|
||||||
scrollPane.setStyle("-fx-background-color: -fx-background");
|
scrollPane.setStyle("-fx-background-color: -fx-background");
|
||||||
add(scrollPane, 0, 1);
|
add(scrollPane, 0, 1);
|
||||||
GridPane.setHgrow(scrollPane, Priority.ALWAYS);
|
GridPane.setHgrow(scrollPane, Priority.ALWAYS);
|
||||||
|
|
||||||
Button add = new Button("Add");
|
var add = new Button("Add");
|
||||||
add.setOnAction(this::add);
|
add.setOnAction(this::add);
|
||||||
Button delete = new Button("Delete");
|
var delete = new Button("Delete");
|
||||||
delete.setOnAction(this::delete);
|
delete.setOnAction(this::delete);
|
||||||
delete.setDisable(true);
|
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
|
buttons.setStyle("-fx-background-color: -fx-background"); // workaround so that the buttons don't shrink
|
||||||
add(buttons, 0, 2);
|
add(buttons, 0, 2);
|
||||||
|
|
||||||
|
@ -119,15 +119,15 @@ public class ActionSettingsPanel extends GridPane {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void add(ActionEvent evt) {
|
private void add(ActionEvent evt) {
|
||||||
Pane actionPane = createActionPane();
|
var actionPane = createActionPane();
|
||||||
Stage dialog = new Stage();
|
var dialog = new Stage();
|
||||||
dialog.initModality(Modality.APPLICATION_MODAL);
|
dialog.initModality(Modality.APPLICATION_MODAL);
|
||||||
dialog.initOwner(getScene().getWindow());
|
dialog.initOwner(getScene().getWindow());
|
||||||
dialog.setTitle("New Action");
|
dialog.setTitle("New Action");
|
||||||
InputStream icon = getClass().getResourceAsStream("/icon.png");
|
InputStream icon = getClass().getResourceAsStream("/icon.png");
|
||||||
dialog.getIcons().add(new Image(icon));
|
dialog.getIcons().add(new Image(icon));
|
||||||
Wizard root = new Wizard(dialog, this::validateSettings, actionPane);
|
var root = new Wizard(dialog, this::validateSettings, actionPane);
|
||||||
Scene scene = new Scene(root, 800, 540);
|
var scene = new Scene(root, 800, 540);
|
||||||
scene.getStylesheets().addAll(getScene().getStylesheets());
|
scene.getStylesheets().addAll(getScene().getStylesheets());
|
||||||
dialog.setScene(scene);
|
dialog.setScene(scene);
|
||||||
centerOnParent(dialog);
|
centerOnParent(dialog);
|
||||||
|
@ -138,58 +138,58 @@ public class ActionSettingsPanel extends GridPane {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createEventHandler() {
|
private void createEventHandler() {
|
||||||
EventHandlerConfiguration config = new EventHandlerConfiguration();
|
var config = new EventHandlerConfiguration();
|
||||||
config.setName(name.getText());
|
config.setName(name.getText());
|
||||||
config.setEvent(event.getValue());
|
config.setEvent(event.getValue());
|
||||||
if(event.getValue() == Event.Type.MODEL_STATUS_CHANGED) {
|
if(event.getValue() == Event.Type.MODEL_STATUS_CHANGED) {
|
||||||
PredicateConfiguration pc = new PredicateConfiguration();
|
var pc = new PredicateConfiguration();
|
||||||
pc.setType(ModelStatePredicate.class.getName());
|
pc.setType(ModelStatePredicate.class.getName());
|
||||||
pc.getConfiguration().put("state", modelState.getValue().name());
|
pc.getConfiguration().put("state", modelState.getValue().name());
|
||||||
pc.setName("state = " + modelState.getValue().toString());
|
pc.setName("state = " + modelState.getValue().toString());
|
||||||
config.getPredicates().add(pc);
|
config.getPredicates().add(pc);
|
||||||
} else if(event.getValue() == Event.Type.RECORDING_STATUS_CHANGED) {
|
} else if(event.getValue() == Event.Type.RECORDING_STATUS_CHANGED) {
|
||||||
PredicateConfiguration pc = new PredicateConfiguration();
|
var pc = new PredicateConfiguration();
|
||||||
pc.setType(RecordingStatePredicate.class.getName());
|
pc.setType(RecordingStatePredicate.class.getName());
|
||||||
pc.getConfiguration().put("state", recordingState.getValue().name());
|
pc.getConfiguration().put("state", recordingState.getValue().name());
|
||||||
pc.setName("state = " + recordingState.getValue().toString());
|
pc.setName("state = " + recordingState.getValue().toString());
|
||||||
config.getPredicates().add(pc);
|
config.getPredicates().add(pc);
|
||||||
} else if(event.getValue() == Event.Type.NO_SPACE_LEFT) {
|
} else if(event.getValue() == Event.Type.NO_SPACE_LEFT) {
|
||||||
PredicateConfiguration pc = new PredicateConfiguration();
|
var pc = new PredicateConfiguration();
|
||||||
pc.setType(MatchAllPredicate.class.getName());
|
pc.setType(MatchAllPredicate.class.getName());
|
||||||
pc.setName("no space left");
|
pc.setName("no space left");
|
||||||
config.getPredicates().add(pc);
|
config.getPredicates().add(pc);
|
||||||
}
|
}
|
||||||
if(!modelSelectionPane.isAllSelected()) {
|
if(!modelSelectionPane.isAllSelected()) {
|
||||||
PredicateConfiguration pc = new PredicateConfiguration();
|
var pc = new PredicateConfiguration();
|
||||||
pc.setType(ModelPredicate.class.getName());
|
pc.setType(ModelPredicate.class.getName());
|
||||||
pc.setModels(modelSelectionPane.getSelectedItems());
|
pc.setModels(modelSelectionPane.getSelectedItems());
|
||||||
pc.setName("model is one of:" + modelSelectionPane.getSelectedItems());
|
pc.setName("model is one of:" + modelSelectionPane.getSelectedItems());
|
||||||
config.getPredicates().add(pc);
|
config.getPredicates().add(pc);
|
||||||
}
|
}
|
||||||
if(showNotification.isSelected()) {
|
if(showNotification.isSelected()) {
|
||||||
ActionConfiguration ac = new ActionConfiguration();
|
var ac = new ActionConfiguration();
|
||||||
ac.setType(ShowNotification.class.getName());
|
ac.setType(ShowNotification.class.getName());
|
||||||
ac.setName("show notification");
|
ac.setName("show notification");
|
||||||
config.getActions().add(ac);
|
config.getActions().add(ac);
|
||||||
}
|
}
|
||||||
if(playSound.isSelected()) {
|
if(playSound.isSelected()) {
|
||||||
ActionConfiguration ac = new ActionConfiguration();
|
var ac = new ActionConfiguration();
|
||||||
ac.setType(PlaySound.class.getName());
|
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.getConfiguration().put("file", file.getAbsolutePath());
|
||||||
ac.setName("play " + file.getName());
|
ac.setName("play " + file.getName());
|
||||||
config.getActions().add(ac);
|
config.getActions().add(ac);
|
||||||
}
|
}
|
||||||
if(executeProgram.isSelected()) {
|
if(executeProgram.isSelected()) {
|
||||||
ActionConfiguration ac = new ActionConfiguration();
|
var ac = new ActionConfiguration();
|
||||||
ac.setType(ExecuteProgram.class.getName());
|
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.getConfiguration().put("file", file.getAbsolutePath());
|
||||||
ac.setName("execute " + file.getName());
|
ac.setName("execute " + file.getName());
|
||||||
config.getActions().add(ac);
|
config.getActions().add(ac);
|
||||||
}
|
}
|
||||||
|
|
||||||
EventHandler handler = new EventHandler(config);
|
var handler = new EventHandler(config);
|
||||||
EventBusHolder.register(handler);
|
EventBusHolder.register(handler);
|
||||||
Config.getInstance().getSettings().eventHandlers.add(config);
|
Config.getInstance().getSettings().eventHandlers.add(config);
|
||||||
actionTable.getItems().add(config);
|
actionTable.getItems().add(config);
|
||||||
|
@ -229,7 +229,7 @@ public class ActionSettingsPanel extends GridPane {
|
||||||
modelState.prefWidthProperty().bind(event.widthProperty());
|
modelState.prefWidthProperty().bind(event.widthProperty());
|
||||||
name.prefWidthProperty().bind(event.widthProperty());
|
name.prefWidthProperty().bind(event.widthProperty());
|
||||||
|
|
||||||
int row = 0;
|
var row = 0;
|
||||||
layout.add(new Label("Name"), 0, row);
|
layout.add(new Label("Name"), 0, row);
|
||||||
layout.add(name, 1, row++);
|
layout.add(name, 1, row++);
|
||||||
|
|
||||||
|
@ -243,7 +243,7 @@ public class ActionSettingsPanel extends GridPane {
|
||||||
layout.add(event, 1, row++);
|
layout.add(event, 1, row++);
|
||||||
|
|
||||||
event.getSelectionModel().selectedItemProperty().addListener((obs, oldV, newV) -> {
|
event.getSelectionModel().selectedItemProperty().addListener((obs, oldV, newV) -> {
|
||||||
boolean modelRelatedStuffDisabled = false;
|
var modelRelatedStuffDisabled = false;
|
||||||
if(newV == Event.Type.NO_SPACE_LEFT) {
|
if(newV == Event.Type.NO_SPACE_LEFT) {
|
||||||
modelRelatedStuffDisabled = true;
|
modelRelatedStuffDisabled = true;
|
||||||
modelSelectionPane.selectAll();
|
modelSelectionPane.selectAll();
|
||||||
|
@ -265,7 +265,7 @@ public class ActionSettingsPanel extends GridPane {
|
||||||
|
|
||||||
layout.add(createSeparator(), 0, row++);
|
layout.add(createSeparator(), 0, row++);
|
||||||
|
|
||||||
Label l = new Label("Models");
|
var l = new Label("Models");
|
||||||
layout.add(l, 0, row);
|
layout.add(l, 0, row);
|
||||||
modelSelectionPane = new ListSelectionPane<>(recorder.getModels(), Collections.emptyList());
|
modelSelectionPane = new ListSelectionPane<>(recorder.getModels(), Collections.emptyList());
|
||||||
layout.add(modelSelectionPane, 1, row++);
|
layout.add(modelSelectionPane, 1, row++);
|
||||||
|
@ -278,8 +278,8 @@ public class ActionSettingsPanel extends GridPane {
|
||||||
layout.add(showNotification, 0, row);
|
layout.add(showNotification, 0, row);
|
||||||
layout.add(testNotification, 1, row++);
|
layout.add(testNotification, 1, row++);
|
||||||
testNotification.setOnAction(evt -> {
|
testNotification.setOnAction(evt -> {
|
||||||
DateTimeFormatter format = DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM);
|
var format = DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM);
|
||||||
ZonedDateTime time = ZonedDateTime.now();
|
var time = ZonedDateTime.now();
|
||||||
DesktopIntegration.notification(CamrecApplication.title, "Test Notification", "Oi, what's up! " + format.format(time));
|
DesktopIntegration.notification(CamrecApplication.title, "Test Notification", "Oi, what's up! " + format.format(time));
|
||||||
});
|
});
|
||||||
testNotification.disableProperty().bind(showNotification.selectedProperty().not());
|
testNotification.disableProperty().bind(showNotification.selectedProperty().not());
|
||||||
|
@ -306,12 +306,12 @@ public class ActionSettingsPanel extends GridPane {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Node createSeparator() {
|
private Node createSeparator() {
|
||||||
Separator divider = new Separator(Orientation.HORIZONTAL);
|
var divider = new Separator(Orientation.HORIZONTAL);
|
||||||
GridPane.setHgrow(divider, Priority.ALWAYS);
|
GridPane.setHgrow(divider, Priority.ALWAYS);
|
||||||
GridPane.setFillWidth(divider, true);
|
GridPane.setFillWidth(divider, true);
|
||||||
GridPane.setColumnSpan(divider, 2);
|
GridPane.setColumnSpan(divider, 2);
|
||||||
int tb = 20;
|
var tb = 20;
|
||||||
int lr = 0;
|
var lr = 0;
|
||||||
GridPane.setMargin(divider, new Insets(tb, lr, tb, lr));
|
GridPane.setMargin(divider, new Insets(tb, lr, tb, lr));
|
||||||
return divider;
|
return divider;
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,7 @@ public class ColorSettingsPane extends HBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String toWeb(Color value) {
|
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.getRed() * 255)));
|
||||||
sb.append(toHex((int) (value.getGreen() * 255)));
|
sb.append(toHex((int) (value.getGreen() * 255)));
|
||||||
sb.append(toHex((int) (value.getBlue() * 255)));
|
sb.append(toHex((int) (value.getBlue() * 255)));
|
||||||
|
@ -72,7 +72,7 @@ public class ColorSettingsPane extends HBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
private CharSequence toHex(int v) {
|
private CharSequence toHex(int v) {
|
||||||
StringBuilder sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
if(v < 16) {
|
if(v < 16) {
|
||||||
sb.append('0');
|
sb.append('0');
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,13 +18,13 @@ public class CreateContactSheetPaneFactory extends AbstractPostProcessingPaneFac
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Preferences doCreatePostProcessorPane(PostProcessor pp) {
|
public Preferences doCreatePostProcessorPane(PostProcessor pp) {
|
||||||
SimpleStringProperty totalSize = new SimpleStringProperty(null, TOTAL_SIZE, pp.getConfig().getOrDefault(TOTAL_SIZE, "1920"));
|
var totalSize = new SimpleStringProperty(null, TOTAL_SIZE, pp.getConfig().getOrDefault(TOTAL_SIZE, "1920"));
|
||||||
SimpleStringProperty padding = new SimpleStringProperty(null, PADDING, pp.getConfig().getOrDefault(PADDING, "4"));
|
var padding = new SimpleStringProperty(null, PADDING, pp.getConfig().getOrDefault(PADDING, "4"));
|
||||||
SimpleStringProperty cols = new SimpleStringProperty(null, COLS, pp.getConfig().getOrDefault(COLS, "8"));
|
var cols = new SimpleStringProperty(null, COLS, pp.getConfig().getOrDefault(COLS, "8"));
|
||||||
SimpleStringProperty rows = new SimpleStringProperty(null, ROWS, pp.getConfig().getOrDefault(ROWS, "7"));
|
var rows = new SimpleStringProperty(null, ROWS, pp.getConfig().getOrDefault(ROWS, "7"));
|
||||||
SimpleStringProperty filename = new SimpleStringProperty(null, FILENAME, pp.getConfig().getOrDefault(FILENAME, "contactsheet.jpg"));
|
var filename = new SimpleStringProperty(null, FILENAME, pp.getConfig().getOrDefault(FILENAME, "contactsheet.jpg"));
|
||||||
background = new SimpleStringProperty(null, BACKGROUND, pp.getConfig().getOrDefault(BACKGROUND, "0x333333"));
|
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())));
|
Boolean.valueOf(pp.getConfig().getOrDefault(BURN_IN_TIMESTAMP, TRUE.toString())));
|
||||||
properties.add(totalSize);
|
properties.add(totalSize);
|
||||||
properties.add(padding);
|
properties.add(padding);
|
||||||
|
@ -34,8 +34,8 @@ public class CreateContactSheetPaneFactory extends AbstractPostProcessingPaneFac
|
||||||
properties.add(background);
|
properties.add(background);
|
||||||
properties.add(burnTimestamp);
|
properties.add(burnTimestamp);
|
||||||
|
|
||||||
Setting backgroundSetting = Setting.of("", background, "Hexadecimal value of the background color for the space between the thumbnails");
|
var backgroundSetting = Setting.of("", background, "Hexadecimal value of the background color for the space between the thumbnails");
|
||||||
Preferences prefs = Preferences.of(new MapPreferencesStorage(),
|
var prefs = Preferences.of(new MapPreferencesStorage(),
|
||||||
Category.of(pp.getName(),
|
Category.of(pp.getName(),
|
||||||
Setting.of("Total Width", totalSize, "Total width of the generated contact sheet"),
|
Setting.of("Total Width", totalSize, "Total width of the generated contact sheet"),
|
||||||
Setting.of("Padding", padding, "Padding between the thumbnails"),
|
Setting.of("Padding", padding, "Padding between the thumbnails"),
|
||||||
|
@ -59,8 +59,8 @@ public class CreateContactSheetPaneFactory extends AbstractPostProcessingPaneFac
|
||||||
}
|
}
|
||||||
|
|
||||||
private ColorPicker createColorPicker(String hexColor) {
|
private ColorPicker createColorPicker(String hexColor) {
|
||||||
Color preselection = Color.web(hexColor);
|
var preselection = Color.web(hexColor);
|
||||||
ColorPicker colorPicker = new ColorPicker(preselection);
|
var colorPicker = new ColorPicker(preselection);
|
||||||
colorPicker.setOnAction(e -> background.set(colorPicker.getValue().toString()));
|
colorPicker.setOnAction(e -> background.set(colorPicker.getValue().toString()));
|
||||||
return colorPicker;
|
return colorPicker;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package ctbrec.ui.settings;
|
package ctbrec.ui.settings;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
@ -71,55 +70,55 @@ public class CtbrecPreferencesStorage implements PreferencesStorage {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Node createGui(Setting setting) throws Exception {
|
public Node createGui(Setting setting) throws NoSuchFieldException, IllegalAccessException {
|
||||||
config.disableSaving();
|
config.disableSaving();
|
||||||
try {
|
try {
|
||||||
Property<?> prop = setting.getProperty();
|
Property<?> prop = setting.getProperty();
|
||||||
if (prop instanceof ExclusiveSelectionProperty) {
|
if (prop instanceof ExclusiveSelectionProperty) {
|
||||||
return createRadioGroup(setting);
|
return createRadioGroup(setting);
|
||||||
} else if (prop instanceof SimpleRangeProperty) {
|
} else if (prop instanceof SimpleRangeProperty) {
|
||||||
return createRangeSlider(setting);
|
return createRangeSlider(setting);
|
||||||
} else if (prop instanceof SimpleDirectoryProperty) {
|
} else if (prop instanceof SimpleDirectoryProperty) {
|
||||||
return createDirectorySelector(setting);
|
return createDirectorySelector(setting);
|
||||||
} else if (prop instanceof SimpleFileProperty) {
|
} else if (prop instanceof SimpleFileProperty) {
|
||||||
return createFileSelector(setting);
|
return createFileSelector(setting);
|
||||||
} else if (prop instanceof IntegerProperty) {
|
} else if (prop instanceof IntegerProperty) {
|
||||||
return createIntegerProperty(setting);
|
return createIntegerProperty(setting);
|
||||||
} else if (prop instanceof LongProperty) {
|
} else if (prop instanceof LongProperty) {
|
||||||
return createLongProperty(setting);
|
return createLongProperty(setting);
|
||||||
} else if (prop instanceof BooleanProperty) {
|
} else if (prop instanceof BooleanProperty) {
|
||||||
return createBooleanProperty(setting);
|
return createBooleanProperty(setting);
|
||||||
} else if (prop instanceof ListProperty) {
|
} else if (prop instanceof ListProperty) {
|
||||||
return createComboBox(setting);
|
return createComboBox(setting);
|
||||||
} else if (prop instanceof StringProperty) {
|
} else if (prop instanceof StringProperty) {
|
||||||
return createStringProperty(setting);
|
return createStringProperty(setting);
|
||||||
} else {
|
} else {
|
||||||
return new Label("Unsupported Type for key " + setting.getKey() + ": " + setting.getProperty());
|
return new Label("Unsupported Type for key " + setting.getKey() + ": " + setting.getProperty());
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
config.enableSaving();
|
config.enableSaving();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Node createRadioGroup(Setting setting) {
|
private Node createRadioGroup(Setting setting) {
|
||||||
ExclusiveSelectionProperty prop = (ExclusiveSelectionProperty) setting.getProperty();
|
ExclusiveSelectionProperty prop = (ExclusiveSelectionProperty) setting.getProperty();
|
||||||
ToggleGroup toggleGroup = new ToggleGroup();
|
var toggleGroup = new ToggleGroup();
|
||||||
RadioButton optionA = new RadioButton(prop.getOptionA());
|
var optionA = new RadioButton(prop.getOptionA());
|
||||||
optionA.setSelected(prop.getValue());
|
optionA.setSelected(prop.getValue());
|
||||||
optionA.setToggleGroup(toggleGroup);
|
optionA.setToggleGroup(toggleGroup);
|
||||||
RadioButton optionB = new RadioButton(prop.getOptionB());
|
var optionB = new RadioButton(prop.getOptionB());
|
||||||
optionB.setSelected(!optionA.isSelected());
|
optionB.setSelected(!optionA.isSelected());
|
||||||
optionB.setToggleGroup(toggleGroup);
|
optionB.setToggleGroup(toggleGroup);
|
||||||
optionA.selectedProperty().bindBidirectional(prop);
|
optionA.selectedProperty().bindBidirectional(prop);
|
||||||
prop.addListener((obs, oldV, newV) -> saveValue(() -> {
|
prop.addListener((obs, oldV, newV) -> saveValue(() -> {
|
||||||
Field field = Settings.class.getField(setting.getKey());
|
var field = Settings.class.getField(setting.getKey());
|
||||||
field.set(settings, newV);
|
field.set(settings, newV); // NOSONAR
|
||||||
if (setting.doesNeedRestart() && !Objects.equals(oldV, newV)) {
|
if (setting.doesNeedRestart() && !Objects.equals(oldV, newV)) {
|
||||||
runRestartRequiredCallback();
|
runRestartRequiredCallback();
|
||||||
}
|
}
|
||||||
config.save();
|
config.save();
|
||||||
}));
|
}));
|
||||||
HBox row = new HBox();
|
var row = new HBox();
|
||||||
row.getChildren().addAll(optionA, optionB);
|
row.getChildren().addAll(optionA, optionB);
|
||||||
HBox.setMargin(optionA, new Insets(5));
|
HBox.setMargin(optionA, new Insets(5));
|
||||||
HBox.setMargin(optionB, 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.setHigh(highValue >= 0 ? highValue : values.get(values.size() - 1));
|
||||||
resolutionRange.getLow().addListener((obs, o, n) -> saveValue(() -> {
|
resolutionRange.getLow().addListener((obs, o, n) -> saveValue(() -> {
|
||||||
int newV = labels.get(n.intValue());
|
int newV = labels.get(n.intValue());
|
||||||
Field field = Settings.class.getField(rangeProperty.getLowKey());
|
var field = Settings.class.getField(rangeProperty.getLowKey());
|
||||||
field.set(settings, newV);
|
field.set(settings, newV); // NOSONAR
|
||||||
config.save();
|
config.save();
|
||||||
}));
|
}));
|
||||||
resolutionRange.getHigh().addListener((obs, o, n) -> saveValue(() -> {
|
resolutionRange.getHigh().addListener((obs, o, n) -> saveValue(() -> {
|
||||||
int newV = labels.get(n.intValue());
|
int newV = labels.get(n.intValue());
|
||||||
Field field = Settings.class.getField(rangeProperty.getHighKey());
|
var field = Settings.class.getField(rangeProperty.getHighKey());
|
||||||
field.set(settings, newV);
|
field.set(settings, newV); // NOSONAR
|
||||||
config.save();
|
config.save();
|
||||||
}));
|
}));
|
||||||
return resolutionRange;
|
return resolutionRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getRangeSliderValue(List<Integer> values, List<Integer> labels, int value) {
|
private int getRangeSliderValue(List<Integer> values, List<Integer> labels, int value) {
|
||||||
for (int i = 0; i < labels.size(); i++) {
|
for (var i = 0; i < labels.size(); i++) {
|
||||||
int label = labels.get(i).intValue();
|
var label = labels.get(i).intValue();
|
||||||
if (label == value) {
|
if (label == value) {
|
||||||
return values.get(i);
|
return values.get(i);
|
||||||
}
|
}
|
||||||
|
@ -175,13 +174,13 @@ public class CtbrecPreferencesStorage implements PreferencesStorage {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Node createFileSelector(Setting setting) {
|
private Node createFileSelector(Setting setting) {
|
||||||
ProgramSelectionBox programSelector = new ProgramSelectionBox("");
|
var programSelector = new ProgramSelectionBox("");
|
||||||
programSelector.fileProperty().addListener((obs, o, n) -> saveValue(() -> {
|
programSelector.fileProperty().addListener((obs, o, n) -> saveValue(() -> {
|
||||||
String path = n;
|
String path = n;
|
||||||
Field field = Settings.class.getField(setting.getKey());
|
var field = Settings.class.getField(setting.getKey());
|
||||||
String oldValue = (String) field.get(settings);
|
String oldValue = (String) field.get(settings);
|
||||||
if (!Objects.equals(path, oldValue)) {
|
if (!Objects.equals(path, oldValue)) {
|
||||||
field.set(settings, path);
|
field.set(settings, path); // NOSONAR
|
||||||
if (setting.doesNeedRestart()) {
|
if (setting.doesNeedRestart()) {
|
||||||
runRestartRequiredCallback();
|
runRestartRequiredCallback();
|
||||||
}
|
}
|
||||||
|
@ -194,14 +193,14 @@ public class CtbrecPreferencesStorage implements PreferencesStorage {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Node createDirectorySelector(Setting setting) {
|
private Node createDirectorySelector(Setting setting) {
|
||||||
DirectorySelectionBox directorySelector = new DirectorySelectionBox("");
|
var directorySelector = new DirectorySelectionBox("");
|
||||||
directorySelector.prefWidth(400);
|
directorySelector.prefWidth(400);
|
||||||
directorySelector.fileProperty().addListener((obs, o, n) -> saveValue(() -> {
|
directorySelector.fileProperty().addListener((obs, o, n) -> saveValue(() -> {
|
||||||
String path = n;
|
String path = n;
|
||||||
Field field = Settings.class.getField(setting.getKey());
|
var field = Settings.class.getField(setting.getKey());
|
||||||
String oldValue = (String) field.get(settings);
|
String oldValue = (String) field.get(settings);
|
||||||
if (!Objects.equals(path, oldValue)) {
|
if (!Objects.equals(path, oldValue)) {
|
||||||
field.set(settings, path);
|
field.set(settings, path); // NOSONAR
|
||||||
if (setting.doesNeedRestart()) {
|
if (setting.doesNeedRestart()) {
|
||||||
runRestartRequiredCallback();
|
runRestartRequiredCallback();
|
||||||
}
|
}
|
||||||
|
@ -214,10 +213,10 @@ public class CtbrecPreferencesStorage implements PreferencesStorage {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Node createStringProperty(Setting setting) {
|
private Node createStringProperty(Setting setting) {
|
||||||
TextField ctrl = new TextField();
|
var ctrl = new TextField();
|
||||||
ctrl.textProperty().addListener((obs, oldV, newV) -> saveValue(() -> {
|
ctrl.textProperty().addListener((obs, oldV, newV) -> saveValue(() -> {
|
||||||
Field field = Settings.class.getField(setting.getKey());
|
var field = Settings.class.getField(setting.getKey());
|
||||||
field.set(settings, newV);
|
field.set(settings, newV); // NOSONAR
|
||||||
if (setting.doesNeedRestart() && !Objects.equals(oldV, newV)) {
|
if (setting.doesNeedRestart() && !Objects.equals(oldV, newV)) {
|
||||||
runRestartRequiredCallback();
|
runRestartRequiredCallback();
|
||||||
}
|
}
|
||||||
|
@ -230,14 +229,14 @@ public class CtbrecPreferencesStorage implements PreferencesStorage {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private Node createIntegerProperty(Setting setting) {
|
private Node createIntegerProperty(Setting setting) {
|
||||||
TextField ctrl = new TextField();
|
var ctrl = new TextField();
|
||||||
ctrl.textProperty().addListener((obs, oldV, newV) -> saveValue(() -> {
|
ctrl.textProperty().addListener((obs, oldV, newV) -> saveValue(() -> {
|
||||||
if (!newV.matches("\\d*")) {
|
if (!newV.matches("\\d*")) {
|
||||||
ctrl.setText(newV.replaceAll(PATTERN_NOT_A_DIGIT, ""));
|
ctrl.setText(newV.replaceAll(PATTERN_NOT_A_DIGIT, ""));
|
||||||
}
|
}
|
||||||
if (!ctrl.getText().isEmpty()) {
|
if (!ctrl.getText().isEmpty()) {
|
||||||
Field field = Settings.class.getField(setting.getKey());
|
var field = Settings.class.getField(setting.getKey());
|
||||||
field.set(settings, Integer.parseInt(ctrl.getText()));
|
field.set(settings, Integer.parseInt(ctrl.getText())); // NOSONAR
|
||||||
if (setting.doesNeedRestart() && !Objects.equals(oldV, newV) && prefs != null) {
|
if (setting.doesNeedRestart() && !Objects.equals(oldV, newV) && prefs != null) {
|
||||||
runRestartRequiredCallback();
|
runRestartRequiredCallback();
|
||||||
}
|
}
|
||||||
|
@ -251,18 +250,18 @@ public class CtbrecPreferencesStorage implements PreferencesStorage {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private Node createLongProperty(Setting setting) {
|
private Node createLongProperty(Setting setting) {
|
||||||
TextField ctrl = new TextField();
|
var ctrl = new TextField();
|
||||||
ctrl.textProperty().addListener((obs, oldV, newV) -> saveValue(() -> {
|
ctrl.textProperty().addListener((obs, oldV, newV) -> saveValue(() -> {
|
||||||
if (!newV.matches("\\d*")) {
|
if (!newV.matches("\\d*")) {
|
||||||
ctrl.setText(newV.replaceAll(PATTERN_NOT_A_DIGIT, ""));
|
ctrl.setText(newV.replaceAll(PATTERN_NOT_A_DIGIT, ""));
|
||||||
}
|
}
|
||||||
if (!ctrl.getText().isEmpty()) {
|
if (!ctrl.getText().isEmpty()) {
|
||||||
long value = Long.parseLong(ctrl.getText());
|
var value = Long.parseLong(ctrl.getText());
|
||||||
if (setting.getConverter() != null) {
|
if (setting.getConverter() != null) {
|
||||||
value = (long) setting.getConverter().convertFrom(value);
|
value = (long) setting.getConverter().convertFrom(value);
|
||||||
}
|
}
|
||||||
Field field = Settings.class.getField(setting.getKey());
|
var field = Settings.class.getField(setting.getKey());
|
||||||
field.set(settings, value);
|
field.set(settings, value); // NOSONAR
|
||||||
if (setting.doesNeedRestart() && !Objects.equals(oldV, newV)) {
|
if (setting.doesNeedRestart() && !Objects.equals(oldV, newV)) {
|
||||||
runRestartRequiredCallback();
|
runRestartRequiredCallback();
|
||||||
}
|
}
|
||||||
|
@ -275,10 +274,10 @@ public class CtbrecPreferencesStorage implements PreferencesStorage {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Node createBooleanProperty(Setting setting) {
|
private Node createBooleanProperty(Setting setting) {
|
||||||
CheckBox ctrl = new CheckBox();
|
var ctrl = new CheckBox();
|
||||||
ctrl.selectedProperty().addListener((obs, oldV, newV) -> saveValue(() -> {
|
ctrl.selectedProperty().addListener((obs, oldV, newV) -> saveValue(() -> {
|
||||||
Field field = Settings.class.getField(setting.getKey());
|
var field = Settings.class.getField(setting.getKey());
|
||||||
field.set(settings, newV);
|
field.set(settings, newV); // NOSONAR
|
||||||
if (setting.doesNeedRestart() && !Objects.equals(oldV, newV)) {
|
if (setting.doesNeedRestart() && !Objects.equals(oldV, newV)) {
|
||||||
runRestartRequiredCallback();
|
runRestartRequiredCallback();
|
||||||
}
|
}
|
||||||
|
@ -293,7 +292,7 @@ public class CtbrecPreferencesStorage implements PreferencesStorage {
|
||||||
private Node createComboBox(Setting setting) throws NoSuchFieldException, IllegalAccessException {
|
private Node createComboBox(Setting setting) throws NoSuchFieldException, IllegalAccessException {
|
||||||
ListProperty<?> listProp = (ListProperty<?>) setting.getProperty();
|
ListProperty<?> listProp = (ListProperty<?>) setting.getProperty();
|
||||||
ComboBox<Object> comboBox = new ComboBox(listProp);
|
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);
|
Object value = field.get(settings);
|
||||||
if (StringUtil.isNotBlank(value.toString())) {
|
if (StringUtil.isNotBlank(value.toString())) {
|
||||||
if (setting.getConverter() != null) {
|
if (setting.getConverter() != null) {
|
||||||
|
@ -305,9 +304,9 @@ public class CtbrecPreferencesStorage implements PreferencesStorage {
|
||||||
comboBox.valueProperty().addListener((obs, oldV, newV) -> saveValue(() -> {
|
comboBox.valueProperty().addListener((obs, oldV, newV) -> saveValue(() -> {
|
||||||
LOG.debug("Saving setting {}", setting.getKey());
|
LOG.debug("Saving setting {}", setting.getKey());
|
||||||
if (setting.getConverter() != null) {
|
if (setting.getConverter() != null) {
|
||||||
field.set(settings, setting.getConverter().convertFrom(newV));
|
field.set(settings, setting.getConverter().convertFrom(newV)); // NOSONAR
|
||||||
} else {
|
} else {
|
||||||
field.set(settings, newV);
|
field.set(settings, newV); // NOSONAR
|
||||||
}
|
}
|
||||||
if (setting.doesNeedRestart() && !Objects.equals(oldV, newV)) {
|
if (setting.doesNeedRestart() && !Objects.equals(oldV, newV)) {
|
||||||
runRestartRequiredCallback();
|
runRestartRequiredCallback();
|
||||||
|
@ -330,6 +329,6 @@ public class CtbrecPreferencesStorage implements PreferencesStorage {
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
private interface Exec {
|
private interface Exec {
|
||||||
public void run() throws Exception;
|
public void run() throws IllegalAccessException, IOException, NoSuchFieldException;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ public class DeleteTooShortPaneFactory extends AbstractPostProcessingPaneFactory
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Preferences doCreatePostProcessorPane(PostProcessor pp) {
|
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);
|
properties.add(minimumLengthInSeconds);
|
||||||
|
|
||||||
return Preferences.of(new MapPreferencesStorage(),
|
return Preferences.of(new MapPreferencesStorage(),
|
||||||
|
|
|
@ -2,7 +2,6 @@ package ctbrec.ui.settings;
|
||||||
|
|
||||||
import static javafx.scene.control.ButtonType.*;
|
import static javafx.scene.control.ButtonType.*;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
|
@ -57,7 +56,7 @@ public class IgnoreList extends GridPane {
|
||||||
setVgap(10);
|
setVgap(10);
|
||||||
setPadding(new Insets(20, 10, 10, 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");
|
headline.getStyleClass().add("settings-group-label");
|
||||||
add(headline, 0, 0);
|
add(headline, 0, 0);
|
||||||
|
|
||||||
|
@ -71,13 +70,13 @@ public class IgnoreList extends GridPane {
|
||||||
add(ignoreListView, 0, 1);
|
add(ignoreListView, 0, 1);
|
||||||
GridPane.setHgrow(ignoreListView, Priority.ALWAYS);
|
GridPane.setHgrow(ignoreListView, Priority.ALWAYS);
|
||||||
|
|
||||||
Button remove = new Button("Remove");
|
var remove = new Button("Remove");
|
||||||
remove.setOnAction(evt -> removeSelectedModels());
|
remove.setOnAction(evt -> removeSelectedModels());
|
||||||
Button exportIgnoreList = new Button("Export");
|
var exportIgnoreList = new Button("Export");
|
||||||
exportIgnoreList.setOnAction(e -> exportIgnoreList());
|
exportIgnoreList.setOnAction(e -> exportIgnoreList());
|
||||||
Button importIgnoreList = new Button("Import");
|
var importIgnoreList = new Button("Import");
|
||||||
importIgnoreList.setOnAction(e -> importIgnoreList());
|
importIgnoreList.setOnAction(e -> importIgnoreList());
|
||||||
HBox buttons = new HBox(10, remove, exportIgnoreList, importIgnoreList);
|
var buttons = new HBox(10, remove, exportIgnoreList, importIgnoreList);
|
||||||
add(buttons, 0, 2);
|
add(buttons, 0, 2);
|
||||||
buttons.setStyle("-fx-background-color: -fx-background"); // workaround so that the buttons don't shrink
|
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() {
|
private void removeSelectedModels() {
|
||||||
List<String> selectedModels = ignoreListView.getSelectionModel().getSelectedItems();
|
List<String> selectedModels = ignoreListView.getSelectionModel().getSelectedItems();
|
||||||
if (selectedModels.isEmpty()) {
|
if (selectedModels.isEmpty()) {
|
||||||
return;
|
return; // NOSONAR
|
||||||
} else {
|
} else {
|
||||||
Config.getInstance().getSettings().ignoredModels.removeAll(selectedModels);
|
Config.getInstance().getSettings().ignoredModels.removeAll(selectedModels);
|
||||||
ignoreListView.getItems().removeAll(selectedModels);
|
ignoreListView.getItems().removeAll(selectedModels);
|
||||||
|
@ -110,16 +109,16 @@ public class IgnoreList extends GridPane {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void exportIgnoreList() {
|
private void exportIgnoreList() {
|
||||||
FileChooser chooser = new FileChooser();
|
var chooser = new FileChooser();
|
||||||
chooser.setTitle("Export ignore list");
|
chooser.setTitle("Export ignore list");
|
||||||
chooser.setInitialFileName("ctbrec-ignorelist.json");
|
chooser.setInitialFileName("ctbrec-ignorelist.json");
|
||||||
File file = chooser.showSaveDialog(null);
|
var file = chooser.showSaveDialog(null);
|
||||||
if (file != 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);
|
Type modelListType = Types.newParameterizedType(List.class, String.class);
|
||||||
JsonAdapter<List<String>> adapter = moshi.adapter(modelListType);
|
JsonAdapter<List<String>> adapter = moshi.adapter(modelListType);
|
||||||
adapter = adapter.indent(" ");
|
adapter = adapter.indent(" ");
|
||||||
try (FileOutputStream out = new FileOutputStream(file)) {
|
try (var out = new FileOutputStream(file)) {
|
||||||
String json = adapter.toJson(Config.getInstance().getSettings().ignoredModels);
|
String json = adapter.toJson(Config.getInstance().getSettings().ignoredModels);
|
||||||
out.write(json.getBytes(StandardCharsets.UTF_8));
|
out.write(json.getBytes(StandardCharsets.UTF_8));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -129,20 +128,20 @@ public class IgnoreList extends GridPane {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void importIgnoreList() {
|
private void importIgnoreList() {
|
||||||
FileChooser chooser = new FileChooser();
|
var chooser = new FileChooser();
|
||||||
chooser.setTitle("Import ignore list");
|
chooser.setTitle("Import ignore list");
|
||||||
File file = chooser.showOpenDialog(null);
|
var file = chooser.showOpenDialog(null);
|
||||||
if (file != 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);
|
Type modelListType = Types.newParameterizedType(List.class, String.class);
|
||||||
JsonAdapter<List<String>> adapter = moshi.adapter(modelListType);
|
JsonAdapter<List<String>> adapter = moshi.adapter(modelListType);
|
||||||
try {
|
try {
|
||||||
byte[] fileContent = Files.readAllBytes(file.toPath());
|
byte[] fileContent = Files.readAllBytes(file.toPath());
|
||||||
List<String> ignoredModels = adapter.fromJson(new String(fileContent, StandardCharsets.UTF_8));
|
List<String> ignoredModels = adapter.fromJson(new String(fileContent, StandardCharsets.UTF_8));
|
||||||
boolean confirmed = true;
|
var confirmed = true;
|
||||||
if (!Config.getInstance().getSettings().ignoredModels.isEmpty()) {
|
if (!Config.getInstance().getSettings().ignoredModels.isEmpty()) {
|
||||||
String msg = "This will replace the existing ignore list! Continue?";
|
var msg = "This will replace the existing ignore list! Continue?";
|
||||||
AutosizeAlert confirm = new AutosizeAlert(AlertType.CONFIRMATION, msg, getScene(), YES, NO);
|
var confirm = new AutosizeAlert(AlertType.CONFIRMATION, msg, getScene(), YES, NO);
|
||||||
confirm.setTitle("Import ignore list");
|
confirm.setTitle("Import ignore list");
|
||||||
confirm.setHeaderText("Overwrite ignore list");
|
confirm.setHeaderText("Overwrite ignore list");
|
||||||
confirm.showAndWait();
|
confirm.showAndWait();
|
||||||
|
|
|
@ -38,7 +38,7 @@ public class ListSelectionPane<T extends Comparable<T>> extends GridPane {
|
||||||
ObservableList<T> obsAvail = FXCollections.observableArrayList(available);
|
ObservableList<T> obsAvail = FXCollections.observableArrayList(available);
|
||||||
ObservableList<T> obsSel = FXCollections.observableArrayList(selected);
|
ObservableList<T> obsSel = FXCollections.observableArrayList(selected);
|
||||||
for (Iterator<T> iterator = obsAvail.iterator(); iterator.hasNext();) {
|
for (Iterator<T> iterator = obsAvail.iterator(); iterator.hasNext();) {
|
||||||
T t = iterator.next();
|
var t = iterator.next();
|
||||||
if(obsSel.contains(t)) {
|
if(obsSel.contains(t)) {
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
}
|
}
|
||||||
|
@ -52,13 +52,13 @@ public class ListSelectionPane<T extends Comparable<T>> extends GridPane {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createGui() {
|
private void createGui() {
|
||||||
Label labelAvailable = new Label("Available");
|
var labelAvailable = new Label("Available");
|
||||||
Label labelSelected = new Label("Selected");
|
var labelSelected = new Label("Selected");
|
||||||
|
|
||||||
add(labelAvailable, 0, 0);
|
add(labelAvailable, 0, 0);
|
||||||
add(availableListView, 0, 1);
|
add(availableListView, 0, 1);
|
||||||
|
|
||||||
VBox buttonBox = new VBox(5);
|
var buttonBox = new VBox(5);
|
||||||
buttonBox.getChildren().add(addModel);
|
buttonBox.getChildren().add(addModel);
|
||||||
buttonBox.getChildren().add(removeModel);
|
buttonBox.getChildren().add(removeModel);
|
||||||
buttonBox.setAlignment(Pos.CENTER);
|
buttonBox.setAlignment(Pos.CENTER);
|
||||||
|
|
|
@ -11,7 +11,7 @@ public class MoverPaneFactory extends AbstractPostProcessingPaneFactory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Preferences doCreatePostProcessorPane(PostProcessor pp) {
|
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);
|
properties.add(pathTemplate);
|
||||||
|
|
||||||
return Preferences.of(new MapPreferencesStorage(),
|
return Preferences.of(new MapPreferencesStorage(),
|
||||||
|
|
|
@ -1,7 +1,21 @@
|
||||||
package ctbrec.ui.settings;
|
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.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 ctbrec.ui.controls.Dialogs;
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.collections.ListChangeListener;
|
import javafx.collections.ListChangeListener;
|
||||||
|
@ -16,25 +30,20 @@ import javafx.scene.layout.Priority;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
import javafx.stage.Stage;
|
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 {
|
public class PostProcessingStepPanel extends GridPane {
|
||||||
|
|
||||||
private final Config config;
|
private final Config config;
|
||||||
|
|
||||||
private static final Class<?>[] POST_PROCESSOR_CLASSES = new Class<?>[]{ // @formatter: off
|
private static final Class<?>[] POST_PROCESSOR_CLASSES = new Class<?>[]{ // @formatter: off
|
||||||
Copy.class,
|
Copy.class,
|
||||||
Rename.class,
|
Rename.class,
|
||||||
Move.class,
|
Move.class,
|
||||||
Remux.class,
|
Remux.class,
|
||||||
Script.class,
|
Script.class,
|
||||||
DeleteOriginal.class,
|
DeleteOriginal.class,
|
||||||
DeleteTooShort.class,
|
DeleteTooShort.class,
|
||||||
RemoveKeepFile.class,
|
RemoveKeepFile.class,
|
||||||
CreateContactSheet.class
|
CreateContactSheet.class
|
||||||
}; // @formatter: on
|
}; // @formatter: on
|
||||||
|
|
||||||
ListView<PostProcessor> stepListView;
|
ListView<PostProcessor> stepListView;
|
||||||
|
@ -61,7 +70,7 @@ public class PostProcessingStepPanel extends GridPane {
|
||||||
add = createAddButton();
|
add = createAddButton();
|
||||||
remove = createRemoveButton();
|
remove = createRemoveButton();
|
||||||
edit = createEditButton();
|
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 = FXCollections.observableList(config.getSettings().postProcessors);
|
||||||
stepList.addListener((ListChangeListener<PostProcessor>) change -> {
|
stepList.addListener((ListChangeListener<PostProcessor>) change -> {
|
||||||
|
@ -78,7 +87,7 @@ public class PostProcessingStepPanel extends GridPane {
|
||||||
add(buttons, 1, 0);
|
add(buttons, 1, 0);
|
||||||
|
|
||||||
stepListView.getSelectionModel().selectedIndexProperty().addListener((obs, oldV, newV) -> {
|
stepListView.getSelectionModel().selectedIndexProperty().addListener((obs, oldV, newV) -> {
|
||||||
int idx = newV.intValue();
|
var idx = newV.intValue();
|
||||||
boolean noSelection = idx == -1;
|
boolean noSelection = idx == -1;
|
||||||
up.setDisable(noSelection || idx == 0);
|
up.setDisable(noSelection || idx == 0);
|
||||||
down.setDisable(noSelection || idx == stepList.size() - 1);
|
down.setDisable(noSelection || idx == stepList.size() - 1);
|
||||||
|
@ -88,7 +97,7 @@ public class PostProcessingStepPanel extends GridPane {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Button createUpButton() {
|
private Button createUpButton() {
|
||||||
Button button = createButton("\u25B4", "Move step up");
|
var button = createButton("\u25B4", "Move step up");
|
||||||
button.setOnAction(evt -> {
|
button.setOnAction(evt -> {
|
||||||
int idx = stepListView.getSelectionModel().getSelectedIndex();
|
int idx = stepListView.getSelectionModel().getSelectedIndex();
|
||||||
PostProcessor selectedItem = stepListView.getSelectionModel().getSelectedItem();
|
PostProcessor selectedItem = stepListView.getSelectionModel().getSelectedItem();
|
||||||
|
@ -100,7 +109,7 @@ public class PostProcessingStepPanel extends GridPane {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Button createDownButton() {
|
private Button createDownButton() {
|
||||||
Button button = createButton("\u25BE", "Move step down");
|
var button = createButton("\u25BE", "Move step down");
|
||||||
button.setOnAction(evt -> {
|
button.setOnAction(evt -> {
|
||||||
int idx = stepListView.getSelectionModel().getSelectedIndex();
|
int idx = stepListView.getSelectionModel().getSelectedIndex();
|
||||||
PostProcessor selectedItem = stepListView.getSelectionModel().getSelectedItem();
|
PostProcessor selectedItem = stepListView.getSelectionModel().getSelectedItem();
|
||||||
|
@ -112,7 +121,7 @@ public class PostProcessingStepPanel extends GridPane {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Button createAddButton() {
|
private Button createAddButton() {
|
||||||
Button button = createButton("+", "Add a new step");
|
var button = createButton("+", "Add a new step");
|
||||||
button.setDisable(false);
|
button.setDisable(false);
|
||||||
button.setOnAction(evt -> {
|
button.setOnAction(evt -> {
|
||||||
PostProcessor[] options = createOptions();
|
PostProcessor[] options = createOptions();
|
||||||
|
@ -122,7 +131,7 @@ public class PostProcessingStepPanel extends GridPane {
|
||||||
choice.setResizable(true);
|
choice.setResizable(true);
|
||||||
choice.setWidth(600);
|
choice.setWidth(600);
|
||||||
choice.getDialogPane().setMinWidth(400);
|
choice.getDialogPane().setMinWidth(400);
|
||||||
Stage stage = (Stage) choice.getDialogPane().getScene().getWindow();
|
var stage = (Stage) choice.getDialogPane().getScene().getWindow();
|
||||||
stage.getScene().getStylesheets().addAll(getScene().getStylesheets());
|
stage.getScene().getStylesheets().addAll(getScene().getStylesheets());
|
||||||
InputStream icon = Dialogs.class.getResourceAsStream("/icon.png");
|
InputStream icon = Dialogs.class.getResourceAsStream("/icon.png");
|
||||||
stage.getIcons().add(new Image(icon));
|
stage.getIcons().add(new Image(icon));
|
||||||
|
@ -144,8 +153,8 @@ public class PostProcessingStepPanel extends GridPane {
|
||||||
|
|
||||||
private PostProcessor[] createOptions() {
|
private PostProcessor[] createOptions() {
|
||||||
try {
|
try {
|
||||||
PostProcessor[] options = new PostProcessor[POST_PROCESSOR_CLASSES.length];
|
var options = new PostProcessor[POST_PROCESSOR_CLASSES.length];
|
||||||
for (int i = 0; i < POST_PROCESSOR_CLASSES.length; i++) {
|
for (var i = 0; i < POST_PROCESSOR_CLASSES.length; i++) {
|
||||||
Class<?> cls = POST_PROCESSOR_CLASSES[i];
|
Class<?> cls = POST_PROCESSOR_CLASSES[i];
|
||||||
PostProcessor pp;
|
PostProcessor pp;
|
||||||
pp = (PostProcessor) cls.getDeclaredConstructor().newInstance();
|
pp = (PostProcessor) cls.getDeclaredConstructor().newInstance();
|
||||||
|
@ -160,7 +169,7 @@ public class PostProcessingStepPanel extends GridPane {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Button createRemoveButton() {
|
private Button createRemoveButton() {
|
||||||
Button button = createButton("-", "Remove selected step");
|
var button = createButton("-", "Remove selected step");
|
||||||
button.setOnAction(evt -> {
|
button.setOnAction(evt -> {
|
||||||
PostProcessor selectedItem = stepListView.getSelectionModel().getSelectedItem();
|
PostProcessor selectedItem = stepListView.getSelectionModel().getSelectedItem();
|
||||||
if (selectedItem != null) {
|
if (selectedItem != null) {
|
||||||
|
@ -171,7 +180,7 @@ public class PostProcessingStepPanel extends GridPane {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Button createEditButton() {
|
private Button createEditButton() {
|
||||||
Button button = createButton("\u270E", "Edit selected step");
|
var button = createButton("\u270E", "Edit selected step");
|
||||||
button.setOnAction(evt -> {
|
button.setOnAction(evt -> {
|
||||||
PostProcessor selectedItem = stepListView.getSelectionModel().getSelectedItem();
|
PostProcessor selectedItem = stepListView.getSelectionModel().getSelectedItem();
|
||||||
PostProcessingDialogFactory.openEditDialog(selectedItem, getScene(), stepList);
|
PostProcessingDialogFactory.openEditDialog(selectedItem, getScene(), stepList);
|
||||||
|
@ -182,7 +191,7 @@ public class PostProcessingStepPanel extends GridPane {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Button createButton(String text, String tooltip) {
|
private Button createButton(String text, String tooltip) {
|
||||||
Button b = new Button(text);
|
var b = new Button(text);
|
||||||
b.setTooltip(new Tooltip(tooltip));
|
b.setTooltip(new Tooltip(tooltip));
|
||||||
b.setDisable(true);
|
b.setDisable(true);
|
||||||
b.setPrefSize(32, 32);
|
b.setPrefSize(32, 32);
|
||||||
|
|
|
@ -11,8 +11,8 @@ public class RemuxerPaneFactory extends AbstractPostProcessingPaneFactory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Preferences doCreatePostProcessorPane(PostProcessor pp) {
|
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"));
|
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"));
|
||||||
SimpleStringProperty fileExt = new SimpleStringProperty(null, Remux.FILE_EXT, pp.getConfig().getOrDefault(Remux.FILE_EXT, "mp4"));
|
var fileExt = new SimpleStringProperty(null, Remux.FILE_EXT, pp.getConfig().getOrDefault(Remux.FILE_EXT, "mp4"));
|
||||||
properties.add(ffmpegParams);
|
properties.add(ffmpegParams);
|
||||||
properties.add(fileExt);
|
properties.add(fileExt);
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ public class RenamerPaneFactory extends AbstractPostProcessingPaneFactory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Preferences doCreatePostProcessorPane(PostProcessor pp) {
|
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);
|
properties.add(fileTemplate);
|
||||||
|
|
||||||
return Preferences.of(new MapPreferencesStorage(),
|
return Preferences.of(new MapPreferencesStorage(),
|
||||||
|
|
|
@ -11,8 +11,8 @@ public class ScriptPaneFactory extends AbstractPostProcessingPaneFactory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Preferences doCreatePostProcessorPane(PostProcessor pp) {
|
public Preferences doCreatePostProcessorPane(PostProcessor pp) {
|
||||||
SimpleStringProperty script = new SimpleStringProperty(null, Script.SCRIPT_EXECUTABLE, pp.getConfig().getOrDefault(Script.SCRIPT_EXECUTABLE, "c:\\users\\johndoe\\somescript"));
|
var 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 params = new SimpleStringProperty(null, Script.SCRIPT_PARAMS, pp.getConfig().getOrDefault(Script.SCRIPT_PARAMS, "${absolutePath}"));
|
||||||
properties.add(script);
|
properties.add(script);
|
||||||
properties.add(params);
|
properties.add(params);
|
||||||
|
|
||||||
|
|
|
@ -203,8 +203,8 @@ public class SettingsTab extends Tab implements TabSelectionListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createGui() {
|
private void createGui() {
|
||||||
PostProcessingStepPanel postProcessingStepPanel = new PostProcessingStepPanel(config);
|
var postProcessingStepPanel = new PostProcessingStepPanel(config);
|
||||||
Button variablesHelpButton = createHelpButton("Variables", "http://localhost:5689/docs/PostProcessing.md#variables");
|
var variablesHelpButton = createHelpButton("Variables", "http://localhost:5689/docs/PostProcessing.md#variables");
|
||||||
ignoreList = new IgnoreList(sites);
|
ignoreList = new IgnoreList(sites);
|
||||||
List<Category> siteCategories = new ArrayList<>();
|
List<Category> siteCategories = new ArrayList<>();
|
||||||
for (Site site : sites) {
|
for (Site site : sites) {
|
||||||
|
@ -212,8 +212,8 @@ public class SettingsTab extends Tab implements TabSelectionListener {
|
||||||
.ifPresent(configPanel -> siteCategories.add(Category.of(site.getName(), configPanel)));
|
.ifPresent(configPanel -> siteCategories.add(Category.of(site.getName(), configPanel)));
|
||||||
}
|
}
|
||||||
|
|
||||||
CtbrecPreferencesStorage storage = new CtbrecPreferencesStorage(config);
|
var storage = new CtbrecPreferencesStorage(config);
|
||||||
Preferences prefs = Preferences.of(storage,
|
var prefs = Preferences.of(storage,
|
||||||
Category.of("General",
|
Category.of("General",
|
||||||
Group.of("General",
|
Group.of("General",
|
||||||
Setting.of("User-Agent", httpUserAgent),
|
Setting.of("User-Agent", httpUserAgent),
|
||||||
|
@ -304,15 +304,15 @@ public class SettingsTab extends Tab implements TabSelectionListener {
|
||||||
storage.setPreferences(prefs);
|
storage.setPreferences(prefs);
|
||||||
preferencesView.setMinSize(800, 400);
|
preferencesView.setMinSize(800, 400);
|
||||||
preferencesView.setPrefSize(1280, 960);
|
preferencesView.setPrefSize(1280, 960);
|
||||||
ScrollPane scrollPane = new ScrollPane(preferencesView);
|
var scrollPane = new ScrollPane(preferencesView);
|
||||||
GridPane container = new GridPane();
|
var container = new GridPane();
|
||||||
container.add(scrollPane, 0, 0);
|
container.add(scrollPane, 0, 0);
|
||||||
GridPane.setFillWidth(scrollPane, true);
|
GridPane.setFillWidth(scrollPane, true);
|
||||||
GridPane.setFillHeight(scrollPane, true);
|
GridPane.setFillHeight(scrollPane, true);
|
||||||
GridPane.setHgrow(scrollPane, Priority.ALWAYS);
|
GridPane.setHgrow(scrollPane, Priority.ALWAYS);
|
||||||
GridPane.setVgrow(scrollPane, Priority.ALWAYS);
|
GridPane.setVgrow(scrollPane, Priority.ALWAYS);
|
||||||
|
|
||||||
StackPane stackPane = new StackPane();
|
var stackPane = new StackPane();
|
||||||
stackPane.getChildren().add(container);
|
stackPane.getChildren().add(container);
|
||||||
restartNotification = new Label("Restart Required");
|
restartNotification = new Label("Restart Required");
|
||||||
restartNotification.setVisible(false);
|
restartNotification.setVisible(false);
|
||||||
|
@ -369,7 +369,7 @@ public class SettingsTab extends Tab implements TabSelectionListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Button createHelpButton(String text, String url) {
|
private Button createHelpButton(String text, String url) {
|
||||||
Button postProcessingHelpButton = new Button(text);
|
var postProcessingHelpButton = new Button(text);
|
||||||
postProcessingHelpButton.setOnAction(e -> {
|
postProcessingHelpButton.setOnAction(e -> {
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
try {
|
try {
|
||||||
|
@ -446,7 +446,7 @@ public class SettingsTab extends Tab implements TabSelectionListener {
|
||||||
Config.getInstance().getSettings().key = key;
|
Config.getInstance().getSettings().key = key;
|
||||||
saveConfig();
|
saveConfig();
|
||||||
}
|
}
|
||||||
TextInputDialog keyDialog = new TextInputDialog();
|
var keyDialog = new TextInputDialog();
|
||||||
keyDialog.setResizable(true);
|
keyDialog.setResizable(true);
|
||||||
keyDialog.setTitle("Server Authentication");
|
keyDialog.setTitle("Server Authentication");
|
||||||
keyDialog.setHeaderText("A key has been generated");
|
keyDialog.setHeaderText("A key has been generated");
|
||||||
|
@ -485,7 +485,7 @@ public class SettingsTab extends Tab implements TabSelectionListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GridPane createGridLayout() {
|
public static GridPane createGridLayout() {
|
||||||
GridPane layout = new GridPane();
|
var layout = new GridPane();
|
||||||
layout.setPadding(new Insets(10));
|
layout.setPadding(new Insets(10));
|
||||||
layout.setHgap(5);
|
layout.setHgap(5);
|
||||||
layout.setVgap(5);
|
layout.setVgap(5);
|
||||||
|
@ -500,7 +500,7 @@ public class SettingsTab extends Tab implements TabSelectionListener {
|
||||||
fadeIn.setOnFinished(e -> {
|
fadeIn.setOnFinished(e -> {
|
||||||
Transition fadeOut = changeOpacity(restartNotification, 0);
|
Transition fadeOut = changeOpacity(restartNotification, 0);
|
||||||
fadeOut.setOnFinished(e2 -> restartNotification.setVisible(false));
|
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.setOnFinished(evt -> fadeOut.play());
|
||||||
pauseTransition.play();
|
pauseTransition.play();
|
||||||
});
|
});
|
||||||
|
@ -509,7 +509,7 @@ public class SettingsTab extends Tab implements TabSelectionListener {
|
||||||
|
|
||||||
private static final Duration ANIMATION_DURATION = new Duration(500);
|
private static final Duration ANIMATION_DURATION = new Duration(500);
|
||||||
private Transition changeOpacity(Node node, double opacity) {
|
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.setFromValue(node.getOpacity());
|
||||||
transition.setToValue(opacity);
|
transition.setToValue(opacity);
|
||||||
return transition;
|
return transition;
|
||||||
|
@ -536,8 +536,8 @@ public class SettingsTab extends Tab implements TabSelectionListener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int prime = 31;
|
final var prime = 31;
|
||||||
int result = 1;
|
var result = 1;
|
||||||
result = prime * result + value;
|
result = prime * result + value;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -590,8 +590,8 @@ public class SettingsTab extends Tab implements TabSelectionListener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int prime = 31;
|
final var prime = 31;
|
||||||
int result = 1;
|
var result = 1;
|
||||||
result = prime * result + (int) (value ^ (value >>> 32));
|
result = prime * result + (int) (value ^ (value >>> 32));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,17 +90,17 @@ public class Category {
|
||||||
String q = filter.toLowerCase().trim();
|
String q = filter.toLowerCase().trim();
|
||||||
if(hasGroups() || hasSubCategories()) {
|
if(hasGroups() || hasSubCategories()) {
|
||||||
return name.toLowerCase().contains(q)
|
return name.toLowerCase().contains(q)
|
||||||
| groupsContains(q)
|
|| groupsContains(q)
|
||||||
| subCategoriesContains(q);
|
|| subCategoriesContains(q);
|
||||||
} else {
|
} else {
|
||||||
return name.toLowerCase().contains(q)
|
return name.toLowerCase().contains(q)
|
||||||
| guiContains(q);
|
|| guiContains(q);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean subCategoriesContains(String filter) {
|
private boolean subCategoriesContains(String filter) {
|
||||||
boolean contains = false;
|
var contains = false;
|
||||||
if (subCategories != null) {
|
if (subCategories != null) {
|
||||||
for (Category category : subCategories) {
|
for (Category category : subCategories) {
|
||||||
if (category.contains(filter)) {
|
if (category.contains(filter)) {
|
||||||
|
@ -112,7 +112,7 @@ public class Category {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean groupsContains(String filter) {
|
private boolean groupsContains(String filter) {
|
||||||
boolean contains = false;
|
var contains = false;
|
||||||
if (groups != null) {
|
if (groups != null) {
|
||||||
for (Group group : groups) {
|
for (Group group : groups) {
|
||||||
if (group.contains(filter)) {
|
if (group.contains(filter)) {
|
||||||
|
@ -131,9 +131,9 @@ public class Category {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean nodeContains(Node node, String filter) {
|
private boolean nodeContains(Node node, String filter) {
|
||||||
boolean contains = false;
|
var contains = false;
|
||||||
if (node instanceof Pane) {
|
if (node instanceof Pane) {
|
||||||
Pane pane = (Pane) node;
|
var pane = (Pane) node;
|
||||||
for (Node child : pane.getChildren()) {
|
for (Node child : pane.getChildren()) {
|
||||||
contains |= nodeContains(child, filter);
|
contains |= nodeContains(child, filter);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,11 +34,11 @@ public class Group {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean contains(String filter) {
|
public boolean contains(String filter) {
|
||||||
return name.toLowerCase().contains(filter) | settingsContain(filter);
|
return name.toLowerCase().contains(filter) || settingsContain(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean settingsContain(String filter) {
|
private boolean settingsContain(String filter) {
|
||||||
boolean contains = false;
|
var contains = false;
|
||||||
if (settings != null) {
|
if (settings != null) {
|
||||||
for (Setting setting : settings) {
|
for (Setting setting : settings) {
|
||||||
if (setting.contains(filter)) {
|
if (setting.contains(filter)) {
|
||||||
|
|
|
@ -16,7 +16,7 @@ class HighlightingSupport {
|
||||||
private HighlightingSupport() {}
|
private HighlightingSupport() {}
|
||||||
|
|
||||||
static void highlightMatches(Category cat, String filter) {
|
static void highlightMatches(Category cat, String filter) {
|
||||||
Node node = cat.getGuiOrElse(Label::new);
|
var node = cat.getGuiOrElse(Label::new);
|
||||||
highlightMatchess(node, filter);
|
highlightMatchess(node, filter);
|
||||||
if(cat.hasSubCategories()) {
|
if(cat.hasSubCategories()) {
|
||||||
for (Category sub : cat.getSubCategories()) {
|
for (Category sub : cat.getSubCategories()) {
|
||||||
|
@ -26,9 +26,9 @@ class HighlightingSupport {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void highlightMatchess(Node node, String filter) {
|
static void highlightMatchess(Node node, String filter) {
|
||||||
boolean contains = false;
|
var contains = false;
|
||||||
if (node instanceof Pane) {
|
if (node instanceof Pane) {
|
||||||
Pane pane = (Pane) node;
|
var pane = (Pane) node;
|
||||||
for (Node child : pane.getChildren()) {
|
for (Node child : pane.getChildren()) {
|
||||||
highlightMatchess(child, filter);
|
highlightMatchess(child, filter);
|
||||||
}
|
}
|
||||||
|
@ -51,9 +51,9 @@ class HighlightingSupport {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean labelControlContains(Label lbl, String filter) {
|
private static boolean labelControlContains(Label lbl, String filter) {
|
||||||
boolean contains = false;
|
var contains = false;
|
||||||
if (lbl.labelForProperty().get() != null) {
|
if (lbl.labelForProperty().get() != null) {
|
||||||
Node labeledNode = lbl.labelForProperty().get();
|
var labeledNode = lbl.labelForProperty().get();
|
||||||
contains |= labeledNode.toString().toLowerCase().contains(filter);
|
contains |= labeledNode.toString().toLowerCase().contains(filter);
|
||||||
if (labeledNode instanceof Control) {
|
if (labeledNode instanceof Control) {
|
||||||
contains |= ofNullable(((Control) labeledNode).getTooltip()).map(Tooltip::getText).orElse("").toLowerCase().contains(filter);
|
contains |= ofNullable(((Control) labeledNode).getTooltip()).map(Tooltip::getText).orElse("").toLowerCase().contains(filter);
|
||||||
|
@ -66,7 +66,7 @@ class HighlightingSupport {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void removeHighlights(Category cat) {
|
static void removeHighlights(Category cat) {
|
||||||
Node node = cat.getGuiOrElse(Label::new);
|
var node = cat.getGuiOrElse(Label::new);
|
||||||
removeHighlights(node);
|
removeHighlights(node);
|
||||||
if(cat.hasSubCategories()) {
|
if(cat.hasSubCategories()) {
|
||||||
for (Category sub : cat.getSubCategories()) {
|
for (Category sub : cat.getSubCategories()) {
|
||||||
|
|
|
@ -72,17 +72,17 @@ public class Preferences {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Region getView(boolean withNavigation) {
|
public Region getView(boolean withNavigation) {
|
||||||
SearchBox search = new SearchBox(true);
|
var search = new SearchBox(true);
|
||||||
search.textProperty().addListener(this::filterTree);
|
search.textProperty().addListener(this::filterTree);
|
||||||
TreeItem<Category> categoryTreeItems = createCategoryTree(categories, new TreeItem<>(), null);
|
TreeItem<Category> categoryTreeItems = createCategoryTree(categories, new TreeItem<>(), null);
|
||||||
categoryTree = new TreeView<>(categoryTreeItems);
|
categoryTree = new TreeView<>(categoryTreeItems);
|
||||||
categoryTree.showRootProperty().set(false);
|
categoryTree.showRootProperty().set(false);
|
||||||
VBox leftSide = new VBox(search, categoryTree);
|
var leftSide = new VBox(search, categoryTree);
|
||||||
VBox.setVgrow(categoryTree, Priority.ALWAYS);
|
VBox.setVgrow(categoryTree, Priority.ALWAYS);
|
||||||
VBox.setMargin(search, new Insets(2));
|
VBox.setMargin(search, new Insets(2));
|
||||||
VBox.setMargin(categoryTree, new Insets(2));
|
VBox.setMargin(categoryTree, new Insets(2));
|
||||||
|
|
||||||
BorderPane main = new BorderPane();
|
var main = new BorderPane();
|
||||||
if (withNavigation) {
|
if (withNavigation) {
|
||||||
main.setLeft(leftSide);
|
main.setLeft(leftSide);
|
||||||
}
|
}
|
||||||
|
@ -149,9 +149,9 @@ public class Preferences {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Node createPaneWithGroups(Category cat) throws Exception {
|
private Node createPaneWithGroups(Category cat) throws Exception {
|
||||||
VBox pane = new VBox();
|
var pane = new VBox();
|
||||||
for (Group grp : cat.getGroups()) {
|
for (Group grp : cat.getGroups()) {
|
||||||
Label groupLabel = new Label(grp.getName());
|
var groupLabel = new Label(grp.getName());
|
||||||
groupLabel.getStyleClass().add("settings-group-label");
|
groupLabel.getStyleClass().add("settings-group-label");
|
||||||
VBox.setMargin(groupLabel, new Insets(20, 0, 10, 20));
|
VBox.setMargin(groupLabel, new Insets(20, 0, 10, 20));
|
||||||
pane.getChildren().add(groupLabel);
|
pane.getChildren().add(groupLabel);
|
||||||
|
@ -163,13 +163,13 @@ public class Preferences {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Node createGrid(Setting[] settings) throws Exception {
|
private Node createGrid(Setting[] settings) throws Exception {
|
||||||
GridPane pane = new GridPane();
|
var pane = new GridPane();
|
||||||
pane.setHgap(2);
|
pane.setHgap(2);
|
||||||
pane.vgapProperty().bind(pane.hgapProperty());
|
pane.vgapProperty().bind(pane.hgapProperty());
|
||||||
int row = 0;
|
var row = 0;
|
||||||
for (Setting setting : settings) {
|
for (Setting setting : settings) {
|
||||||
Node node = setting.getGui();
|
var node = setting.getGui();
|
||||||
Label label = new Label(setting.getName());
|
var label = new Label(setting.getName());
|
||||||
label.setMinHeight(34);
|
label.setMinHeight(34);
|
||||||
label.labelForProperty().set(node);
|
label.labelForProperty().set(node);
|
||||||
label.setTooltip(new Tooltip(setting.getName()));
|
label.setTooltip(new Tooltip(setting.getName()));
|
||||||
|
@ -226,7 +226,7 @@ public class Preferences {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<Setting> getSetting(String key) {
|
public Optional<Setting> getSetting(String key) {
|
||||||
SettingSearchVisitor search = new SettingSearchVisitor(key);
|
var search = new SettingSearchVisitor(key);
|
||||||
traverse(search);
|
traverse(search);
|
||||||
return search.getResult();
|
return search.getResult();
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,5 +9,5 @@ public interface PreferencesStorage {
|
||||||
void save(Preferences preferences) throws IOException;
|
void save(Preferences preferences) throws IOException;
|
||||||
void load(Preferences preferences);
|
void load(Preferences preferences);
|
||||||
|
|
||||||
Node createGui(Setting setting) throws Exception;
|
Node createGui(Setting setting) throws NoSuchFieldException, IllegalAccessException;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package ctbrec.ui.settings.api;
|
||||||
import static java.util.Optional.*;
|
import static java.util.Optional.*;
|
||||||
|
|
||||||
import ctbrec.StringUtil;
|
import ctbrec.StringUtil;
|
||||||
|
import ctbrec.ui.controls.Dialogs;
|
||||||
import javafx.beans.property.Property;
|
import javafx.beans.property.Property;
|
||||||
import javafx.beans.value.ChangeListener;
|
import javafx.beans.value.ChangeListener;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
|
@ -35,13 +36,13 @@ public class Setting {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Setting of(String name, Property<?> property, String tooltip) {
|
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;
|
setting.tooltip = tooltip;
|
||||||
return setting;
|
return setting;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Setting of(String name, Node gui) {
|
public static Setting of(String name, Node gui) {
|
||||||
Setting setting = new Setting(name, gui);
|
var setting = new Setting(name, gui);
|
||||||
return setting;
|
return setting;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,12 +80,16 @@ public class Setting {
|
||||||
return property;
|
return property;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Node getGui() throws Exception {
|
public Node getGui() {
|
||||||
if (gui == null) {
|
if (gui == null) {
|
||||||
gui = preferencesStorage.createGui(this);
|
try {
|
||||||
if (gui instanceof Control && StringUtil.isNotBlank(tooltip)) {
|
gui = preferencesStorage.createGui(this);
|
||||||
Control control = (Control) gui;
|
if (gui instanceof Control && StringUtil.isNotBlank(tooltip)) {
|
||||||
control.setTooltip(new Tooltip(tooltip));
|
var control = (Control) gui;
|
||||||
|
control.setTooltip(new Tooltip(tooltip));
|
||||||
|
}
|
||||||
|
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||||
|
Dialogs.showError("Error", "Error creating settings GUI", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return gui;
|
return gui;
|
||||||
|
|
|
@ -9,7 +9,7 @@ import ctbrec.Config;
|
||||||
|
|
||||||
public abstract class AbstractConfigUI implements ConfigUI {
|
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() {
|
protected void save() {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package ctbrec.ui.sites.bonga;
|
package ctbrec.ui.sites.bonga;
|
||||||
|
|
||||||
import ctbrec.Config;
|
import ctbrec.Config;
|
||||||
import ctbrec.Settings;
|
|
||||||
import ctbrec.sites.bonga.BongaCams;
|
import ctbrec.sites.bonga.BongaCams;
|
||||||
import ctbrec.ui.DesktopIntegration;
|
import ctbrec.ui.DesktopIntegration;
|
||||||
import ctbrec.ui.settings.SettingsTab;
|
import ctbrec.ui.settings.SettingsTab;
|
||||||
|
@ -26,14 +25,14 @@ public class BongaCamsConfigUI extends AbstractConfigUI {
|
||||||
@Override
|
@Override
|
||||||
public Parent createConfigPanel() {
|
public Parent createConfigPanel() {
|
||||||
GridPane layout = SettingsTab.createGridLayout();
|
GridPane layout = SettingsTab.createGridLayout();
|
||||||
Settings settings = Config.getInstance().getSettings();
|
var settings = Config.getInstance().getSettings();
|
||||||
|
|
||||||
int row = 0;
|
var row = 0;
|
||||||
Label l = new Label("Active");
|
var l = new Label("Active");
|
||||||
layout.add(l, 0, row);
|
layout.add(l, 0, row);
|
||||||
CheckBox enabled = new CheckBox();
|
var enabled = new CheckBox();
|
||||||
enabled.setSelected(!settings.disabledSites.contains(bongaCams.getName()));
|
enabled.setSelected(!settings.disabledSites.contains(bongaCams.getName()));
|
||||||
enabled.setOnAction((e) -> {
|
enabled.setOnAction(e -> {
|
||||||
if(enabled.isSelected()) {
|
if(enabled.isSelected()) {
|
||||||
settings.disabledSites.remove(bongaCams.getName());
|
settings.disabledSites.remove(bongaCams.getName());
|
||||||
} else {
|
} else {
|
||||||
|
@ -45,7 +44,7 @@ public class BongaCamsConfigUI extends AbstractConfigUI {
|
||||||
layout.add(enabled, 1, row++);
|
layout.add(enabled, 1, row++);
|
||||||
|
|
||||||
layout.add(new Label("BongaCams User"), 0, 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.setPrefWidth(300);
|
||||||
username.textProperty().addListener((ob, o, n) -> {
|
username.textProperty().addListener((ob, o, n) -> {
|
||||||
if(!n.equals(Config.getInstance().getSettings().bongaUsername)) {
|
if(!n.equals(Config.getInstance().getSettings().bongaUsername)) {
|
||||||
|
@ -60,7 +59,7 @@ public class BongaCamsConfigUI extends AbstractConfigUI {
|
||||||
layout.add(username, 1, row++);
|
layout.add(username, 1, row++);
|
||||||
|
|
||||||
layout.add(new Label("BongaCams Password"), 0, row);
|
layout.add(new Label("BongaCams Password"), 0, row);
|
||||||
PasswordField password = new PasswordField();
|
var password = new PasswordField();
|
||||||
password.setText(settings.bongaPassword);
|
password.setText(settings.bongaPassword);
|
||||||
password.textProperty().addListener((ob, o, n) -> {
|
password.textProperty().addListener((ob, o, n) -> {
|
||||||
if(!n.equals(Config.getInstance().getSettings().bongaPassword)) {
|
if(!n.equals(Config.getInstance().getSettings().bongaPassword)) {
|
||||||
|
@ -75,7 +74,7 @@ public class BongaCamsConfigUI extends AbstractConfigUI {
|
||||||
layout.add(password, 1, row++);
|
layout.add(password, 1, row++);
|
||||||
|
|
||||||
layout.add(new Label("Bongacams Base URL"), 0, 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.setText(Config.getInstance().getSettings().bongacamsBaseUrl);
|
||||||
baseUrl.textProperty().addListener((ob, o, n) -> {
|
baseUrl.textProperty().addListener((ob, o, n) -> {
|
||||||
Config.getInstance().getSettings().bongacamsBaseUrl = baseUrl.getText();
|
Config.getInstance().getSettings().bongacamsBaseUrl = baseUrl.getText();
|
||||||
|
@ -86,9 +85,9 @@ public class BongaCamsConfigUI extends AbstractConfigUI {
|
||||||
GridPane.setColumnSpan(baseUrl, 2);
|
GridPane.setColumnSpan(baseUrl, 2);
|
||||||
layout.add(baseUrl, 1, row++);
|
layout.add(baseUrl, 1, row++);
|
||||||
|
|
||||||
Button createAccount = new Button("Create new Account");
|
var createAccount = new Button("Create new Account");
|
||||||
createAccount.setOnAction((e) -> DesktopIntegration.open(bongaCams.getAffiliateLink()));
|
createAccount.setOnAction(e -> DesktopIntegration.open(bongaCams.getAffiliateLink()));
|
||||||
layout.add(createAccount, 1, row++);
|
layout.add(createAccount, 1, row);
|
||||||
GridPane.setColumnSpan(createAccount, 2);
|
GridPane.setColumnSpan(createAccount, 2);
|
||||||
GridPane.setMargin(username, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
|
GridPane.setMargin(username, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
|
||||||
GridPane.setMargin(password, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
|
GridPane.setMargin(password, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
|
||||||
|
|
|
@ -7,7 +7,6 @@ import java.util.Collections;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -32,11 +31,11 @@ public class BongaCamsElectronLoginDialog {
|
||||||
this.cookieJar = cookieJar;
|
this.cookieJar = cookieJar;
|
||||||
browser = ExternalBrowser.getInstance();
|
browser = ExternalBrowser.getInstance();
|
||||||
try {
|
try {
|
||||||
JSONObject config = new JSONObject();
|
var config = new JSONObject();
|
||||||
config.put("url", URL);
|
config.put("url", URL);
|
||||||
config.put("w", 640);
|
config.put("w", 640);
|
||||||
config.put("h", 480);
|
config.put("h", 480);
|
||||||
JSONObject msg = new JSONObject();
|
var msg = new JSONObject();
|
||||||
msg.put("config", config);
|
msg.put("config", config);
|
||||||
browser.run(msg, msgHandler);
|
browser.run(msg, msgHandler);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
|
@ -51,9 +50,9 @@ public class BongaCamsElectronLoginDialog {
|
||||||
if(!line.startsWith("{")) {
|
if(!line.startsWith("{")) {
|
||||||
LOG.error("Didn't received a JSON object {}", line);
|
LOG.error("Didn't received a JSON object {}", line);
|
||||||
} else {
|
} else {
|
||||||
JSONObject json = new JSONObject(line);
|
var json = new JSONObject(line);
|
||||||
if(json.has("url")) {
|
if(json.has("url")) {
|
||||||
String url = json.getString("url");
|
var url = json.getString("url");
|
||||||
if(url.endsWith("/login")) {
|
if(url.endsWith("/login")) {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(500);
|
Thread.sleep(500);
|
||||||
|
@ -66,7 +65,7 @@ public class BongaCamsElectronLoginDialog {
|
||||||
password = password.replace("'", "\\'");
|
password = password.replace("'", "\\'");
|
||||||
browser.executeJavaScript("document.getElementById('log_in_password').value = '" + password + "';");
|
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~=\"page_header\"]').css('display','none');",
|
||||||
"$('div[class~=\"header_bar\"]').css('display','none')",
|
"$('div[class~=\"header_bar\"]').css('display','none')",
|
||||||
"$('footer').css('display','none');",
|
"$('footer').css('display','none');",
|
||||||
|
@ -76,15 +75,18 @@ public class BongaCamsElectronLoginDialog {
|
||||||
for (String js : simplify) {
|
for (String js : simplify) {
|
||||||
browser.executeJavaScript(js);
|
browser.executeJavaScript(js);
|
||||||
}
|
}
|
||||||
|
} catch(InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
LOG.warn("Couldn't auto fill username and password for BongaCams", e);
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
LOG.warn("Couldn't auto fill username and password for BongaCams", e);
|
LOG.warn("Couldn't auto fill username and password for BongaCams", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(json.has("cookies")) {
|
if(json.has("cookies")) {
|
||||||
JSONArray cookiesFromBrowser = json.getJSONArray("cookies");
|
var cookiesFromBrowser = json.getJSONArray("cookies");
|
||||||
for (int i = 0; i < cookiesFromBrowser.length(); i++) {
|
for (var i = 0; i < cookiesFromBrowser.length(); i++) {
|
||||||
JSONObject cookie = cookiesFromBrowser.getJSONObject(i);
|
var cookie = cookiesFromBrowser.getJSONObject(i);
|
||||||
if(cookie.getString("domain").contains(DOMAIN)) {
|
if(cookie.getString("domain").contains(DOMAIN)) {
|
||||||
Builder b = new Cookie.Builder()
|
Builder b = new Cookie.Builder()
|
||||||
.path(cookie.getString("path"))
|
.path(cookie.getString("path"))
|
||||||
|
|
|
@ -11,7 +11,7 @@ import ctbrec.ui.tabs.ThumbOverviewTab;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
import javafx.scene.control.Tab;
|
import javafx.scene.control.Tab;
|
||||||
|
|
||||||
public class BongaCamsTabProvider extends TabProvider {
|
public class BongaCamsTabProvider implements TabProvider {
|
||||||
|
|
||||||
private BongaCams bongaCams;
|
private BongaCams bongaCams;
|
||||||
private Recorder recorder;
|
private Recorder recorder;
|
||||||
|
@ -28,7 +28,7 @@ public class BongaCamsTabProvider extends TabProvider {
|
||||||
|
|
||||||
// female
|
// female
|
||||||
String url = BongaCams.baseUrl + "/tools/listing_v3.php?livetab=female&online_only=true&is_mobile=true&offset=";
|
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));
|
tabs.add(createTab("Female", updateService));
|
||||||
|
|
||||||
// male
|
// male
|
||||||
|
@ -67,7 +67,7 @@ public class BongaCamsTabProvider extends TabProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Tab createTab(String title, PaginatedScheduledService updateService) {
|
private Tab createTab(String title, PaginatedScheduledService updateService) {
|
||||||
ThumbOverviewTab tab = new ThumbOverviewTab(title, updateService, bongaCams);
|
var tab = new ThumbOverviewTab(title, updateService, bongaCams);
|
||||||
tab.setRecorder(recorder);
|
tab.setRecorder(recorder);
|
||||||
return tab;
|
return tab;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@ import ctbrec.sites.bonga.BongaCamsModel;
|
||||||
import ctbrec.ui.tabs.PaginatedScheduledService;
|
import ctbrec.ui.tabs.PaginatedScheduledService;
|
||||||
import javafx.concurrent.Task;
|
import javafx.concurrent.Task;
|
||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
import okhttp3.Response;
|
|
||||||
|
|
||||||
public class BongaCamsUpdateService extends PaginatedScheduledService {
|
public class BongaCamsUpdateService extends PaginatedScheduledService {
|
||||||
|
|
||||||
|
@ -38,48 +37,56 @@ public class BongaCamsUpdateService extends PaginatedScheduledService {
|
||||||
return new Task<List<Model>>() {
|
return new Task<List<Model>>() {
|
||||||
@Override
|
@Override
|
||||||
public List<Model> call() throws IOException {
|
public List<Model> call() throws IOException {
|
||||||
String pageUrl = url + ((page-1) * 36);
|
return loadModelList();
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package ctbrec.ui.sites.cam4;
|
package ctbrec.ui.sites.cam4;
|
||||||
|
|
||||||
import ctbrec.Config;
|
import ctbrec.Config;
|
||||||
import ctbrec.Settings;
|
|
||||||
import ctbrec.sites.cam4.Cam4;
|
import ctbrec.sites.cam4.Cam4;
|
||||||
import ctbrec.ui.DesktopIntegration;
|
import ctbrec.ui.DesktopIntegration;
|
||||||
import ctbrec.ui.settings.SettingsTab;
|
import ctbrec.ui.settings.SettingsTab;
|
||||||
|
@ -25,15 +24,15 @@ public class Cam4ConfigUI extends AbstractConfigUI {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Parent createConfigPanel() {
|
public Parent createConfigPanel() {
|
||||||
GridPane layout = SettingsTab.createGridLayout();
|
var layout = SettingsTab.createGridLayout();
|
||||||
Settings settings = Config.getInstance().getSettings();
|
var settings = Config.getInstance().getSettings();
|
||||||
|
|
||||||
int row = 0;
|
var row = 0;
|
||||||
Label l = new Label("Active");
|
var l = new Label("Active");
|
||||||
layout.add(l, 0, row);
|
layout.add(l, 0, row);
|
||||||
CheckBox enabled = new CheckBox();
|
var enabled = new CheckBox();
|
||||||
enabled.setSelected(!settings.disabledSites.contains(cam4.getName()));
|
enabled.setSelected(!settings.disabledSites.contains(cam4.getName()));
|
||||||
enabled.setOnAction((e) -> {
|
enabled.setOnAction(e -> {
|
||||||
if(enabled.isSelected()) {
|
if(enabled.isSelected()) {
|
||||||
settings.disabledSites.remove(cam4.getName());
|
settings.disabledSites.remove(cam4.getName());
|
||||||
} else {
|
} else {
|
||||||
|
@ -45,7 +44,7 @@ public class Cam4ConfigUI extends AbstractConfigUI {
|
||||||
layout.add(enabled, 1, row++);
|
layout.add(enabled, 1, row++);
|
||||||
|
|
||||||
layout.add(new Label("Cam4 User"), 0, 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) -> {
|
username.textProperty().addListener((ob, o, n) -> {
|
||||||
if(!n.equals(Config.getInstance().getSettings().cam4Username)) {
|
if(!n.equals(Config.getInstance().getSettings().cam4Username)) {
|
||||||
Config.getInstance().getSettings().cam4Username = username.getText();
|
Config.getInstance().getSettings().cam4Username = username.getText();
|
||||||
|
@ -59,7 +58,7 @@ public class Cam4ConfigUI extends AbstractConfigUI {
|
||||||
layout.add(username, 1, row++);
|
layout.add(username, 1, row++);
|
||||||
|
|
||||||
layout.add(new Label("Cam4 Password"), 0, row);
|
layout.add(new Label("Cam4 Password"), 0, row);
|
||||||
PasswordField password = new PasswordField();
|
var password = new PasswordField();
|
||||||
password.setText(Config.getInstance().getSettings().cam4Password);
|
password.setText(Config.getInstance().getSettings().cam4Password);
|
||||||
password.textProperty().addListener((ob, o, n) -> {
|
password.textProperty().addListener((ob, o, n) -> {
|
||||||
if(!n.equals(Config.getInstance().getSettings().cam4Password)) {
|
if(!n.equals(Config.getInstance().getSettings().cam4Password)) {
|
||||||
|
@ -73,9 +72,9 @@ public class Cam4ConfigUI extends AbstractConfigUI {
|
||||||
GridPane.setColumnSpan(password, 2);
|
GridPane.setColumnSpan(password, 2);
|
||||||
layout.add(password, 1, row++);
|
layout.add(password, 1, row++);
|
||||||
|
|
||||||
Button createAccount = new Button("Create new Account");
|
var createAccount = new Button("Create new Account");
|
||||||
createAccount.setOnAction((e) -> DesktopIntegration.open(Cam4.AFFILIATE_LINK));
|
createAccount.setOnAction(e -> DesktopIntegration.open(Cam4.AFFILIATE_LINK));
|
||||||
layout.add(createAccount, 1, row++);
|
layout.add(createAccount, 1, row);
|
||||||
GridPane.setColumnSpan(createAccount, 2);
|
GridPane.setColumnSpan(createAccount, 2);
|
||||||
GridPane.setMargin(username, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
|
GridPane.setMargin(username, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
|
||||||
GridPane.setMargin(password, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
|
GridPane.setMargin(password, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
|
||||||
|
|
|
@ -7,7 +7,6 @@ import java.util.Collections;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -32,11 +31,11 @@ public class Cam4ElectronLoginDialog {
|
||||||
this.cookieJar = cookieJar;
|
this.cookieJar = cookieJar;
|
||||||
browser = ExternalBrowser.getInstance();
|
browser = ExternalBrowser.getInstance();
|
||||||
try {
|
try {
|
||||||
JSONObject config = new JSONObject();
|
var config = new JSONObject();
|
||||||
config.put("url", URL);
|
config.put("url", URL);
|
||||||
config.put("w", 480);
|
config.put("w", 480);
|
||||||
config.put("h", 640);
|
config.put("h", 640);
|
||||||
JSONObject msg = new JSONObject();
|
var msg = new JSONObject();
|
||||||
msg.put("config", config);
|
msg.put("config", config);
|
||||||
browser.run(msg, msgHandler);
|
browser.run(msg, msgHandler);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
|
@ -51,9 +50,9 @@ public class Cam4ElectronLoginDialog {
|
||||||
if(!line.startsWith("{")) {
|
if(!line.startsWith("{")) {
|
||||||
LOG.error("Didn't received a JSON object {}", line);
|
LOG.error("Didn't received a JSON object {}", line);
|
||||||
} else {
|
} else {
|
||||||
JSONObject json = new JSONObject(line);
|
var json = new JSONObject(line);
|
||||||
if(json.has("url")) {
|
if (json.has("url")) {
|
||||||
String url = json.getString("url");
|
var url = json.getString("url");
|
||||||
|
|
||||||
if(url.endsWith("/login")) {
|
if(url.endsWith("/login")) {
|
||||||
try {
|
try {
|
||||||
|
@ -76,16 +75,16 @@ public class Cam4ElectronLoginDialog {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(json.has("cookies")) {
|
if(json.has("cookies")) {
|
||||||
JSONArray cookiesFromBrowser = json.getJSONArray("cookies");
|
var cookiesFromBrowser = json.getJSONArray("cookies");
|
||||||
try {
|
try {
|
||||||
for (int i = 0; i < cookiesFromBrowser.length(); i++) {
|
for (var i = 0; i < cookiesFromBrowser.length(); i++) {
|
||||||
JSONObject cookie = cookiesFromBrowser.getJSONObject(i);
|
var cookie = cookiesFromBrowser.getJSONObject(i);
|
||||||
if(cookie.getString("domain").contains("cam4")) {
|
if(cookie.getString("domain").contains("cam4")) {
|
||||||
String domain = cookie.getString("domain");
|
var domain = cookie.getString("domain");
|
||||||
if(domain.startsWith(".")) {
|
if(domain.startsWith(".")) {
|
||||||
domain = domain.substring(1);
|
domain = domain.substring(1);
|
||||||
}
|
}
|
||||||
Cookie c = createCookie(domain, cookie);
|
var c = createCookie(domain, cookie);
|
||||||
cookieJar.saveFromResponse(HttpUrl.parse(url), Collections.singletonList(c));
|
cookieJar.saveFromResponse(HttpUrl.parse(url), Collections.singletonList(c));
|
||||||
c = createCookie("cam4.com", cookie);
|
c = createCookie("cam4.com", cookie);
|
||||||
cookieJar.saveFromResponse(HttpUrl.parse(Cam4.BASE_URI), Collections.singletonList(c));
|
cookieJar.saveFromResponse(HttpUrl.parse(Cam4.BASE_URI), Collections.singletonList(c));
|
||||||
|
|
|
@ -29,17 +29,17 @@ public class Cam4FollowedTab extends ThumbOverviewTab implements FollowedTab {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addOnlineOfflineSelector() {
|
private void addOnlineOfflineSelector() {
|
||||||
ToggleGroup group = new ToggleGroup();
|
var group = new ToggleGroup();
|
||||||
RadioButton online = new RadioButton("online");
|
var online = new RadioButton("online");
|
||||||
online.setToggleGroup(group);
|
online.setToggleGroup(group);
|
||||||
RadioButton offline = new RadioButton("offline");
|
var offline = new RadioButton("offline");
|
||||||
offline.setToggleGroup(group);
|
offline.setToggleGroup(group);
|
||||||
pagination.getChildren().add(online);
|
pagination.getChildren().add(online);
|
||||||
pagination.getChildren().add(offline);
|
pagination.getChildren().add(offline);
|
||||||
HBox.setMargin(online, new Insets(5,5,5,40));
|
HBox.setMargin(online, new Insets(5,5,5,40));
|
||||||
HBox.setMargin(offline, new Insets(5,5,5,5));
|
HBox.setMargin(offline, new Insets(5,5,5,5));
|
||||||
online.setSelected(true);
|
online.setSelected(true);
|
||||||
group.selectedToggleProperty().addListener((e) -> {
|
group.selectedToggleProperty().addListener(e -> {
|
||||||
((Cam4FollowedUpdateService)updateService).setShowOnline(online.isSelected());
|
((Cam4FollowedUpdateService)updateService).setShowOnline(online.isSelected());
|
||||||
queue.clear();
|
queue.clear();
|
||||||
updateService.restart();
|
updateService.restart();
|
||||||
|
@ -66,10 +66,8 @@ public class Cam4FollowedTab extends ThumbOverviewTab implements FollowedTab {
|
||||||
|
|
||||||
public void setScene(Scene scene) {
|
public void setScene(Scene scene) {
|
||||||
scene.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
|
scene.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
|
||||||
if(this.isSelected()) {
|
if (this.isSelected() && event.getCode() == KeyCode.DELETE) {
|
||||||
if(event.getCode() == KeyCode.DELETE) {
|
follow(selectedThumbCells, false);
|
||||||
follow(selectedThumbCells, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ import java.util.List;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import ctbrec.Model;
|
import ctbrec.Model;
|
||||||
|
@ -17,7 +16,6 @@ import ctbrec.ui.SiteUiFactory;
|
||||||
import ctbrec.ui.tabs.PaginatedScheduledService;
|
import ctbrec.ui.tabs.PaginatedScheduledService;
|
||||||
import javafx.concurrent.Task;
|
import javafx.concurrent.Task;
|
||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
import okhttp3.Response;
|
|
||||||
|
|
||||||
public class Cam4FollowedUpdateService extends PaginatedScheduledService {
|
public class Cam4FollowedUpdateService extends PaginatedScheduledService {
|
||||||
|
|
||||||
|
@ -27,7 +25,7 @@ public class Cam4FollowedUpdateService extends PaginatedScheduledService {
|
||||||
public Cam4FollowedUpdateService(Cam4 site) {
|
public Cam4FollowedUpdateService(Cam4 site) {
|
||||||
this.site = site;
|
this.site = site;
|
||||||
ExecutorService executor = Executors.newSingleThreadExecutor(r -> {
|
ExecutorService executor = Executors.newSingleThreadExecutor(r -> {
|
||||||
Thread t = new Thread(r);
|
var t = new Thread(r);
|
||||||
t.setDaemon(true);
|
t.setDaemon(true);
|
||||||
t.setName("ThumbOverviewTab UpdateService");
|
t.setName("ThumbOverviewTab UpdateService");
|
||||||
return t;
|
return t;
|
||||||
|
@ -40,37 +38,45 @@ public class Cam4FollowedUpdateService extends PaginatedScheduledService {
|
||||||
return new Task<List<Model>>() {
|
return new Task<List<Model>>() {
|
||||||
@Override
|
@Override
|
||||||
public List<Model> call() throws IOException {
|
public List<Model> call() throws IOException {
|
||||||
// login first
|
return loadModelList();
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
public void setShowOnline(boolean online) {
|
||||||
this.showOnline = online;
|
this.showOnline = online;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import ctbrec.ui.tabs.ThumbOverviewTab;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
import javafx.scene.control.Tab;
|
import javafx.scene.control.Tab;
|
||||||
|
|
||||||
public class Cam4TabProvider extends TabProvider {
|
public class Cam4TabProvider implements TabProvider {
|
||||||
|
|
||||||
private Cam4 cam4;
|
private Cam4 cam4;
|
||||||
private Recorder recorder;
|
private Recorder recorder;
|
||||||
|
@ -44,8 +44,8 @@ public class Cam4TabProvider extends TabProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Tab createTab(String name, String url) {
|
private Tab createTab(String name, String url) {
|
||||||
Cam4UpdateService updateService = new Cam4UpdateService(url, false, cam4);
|
var updateService = new Cam4UpdateService(url, false, cam4);
|
||||||
ThumbOverviewTab tab = new ThumbOverviewTab(name, updateService, cam4);
|
var tab = new ThumbOverviewTab(name, updateService, cam4);
|
||||||
tab.setRecorder(recorder);
|
tab.setRecorder(recorder);
|
||||||
return tab;
|
return tab;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@ import java.util.concurrent.Executors;
|
||||||
|
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.jsoup.nodes.Element;
|
import org.jsoup.nodes.Element;
|
||||||
import org.jsoup.select.Elements;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -28,7 +27,6 @@ import ctbrec.ui.SiteUiFactory;
|
||||||
import ctbrec.ui.tabs.PaginatedScheduledService;
|
import ctbrec.ui.tabs.PaginatedScheduledService;
|
||||||
import javafx.concurrent.Task;
|
import javafx.concurrent.Task;
|
||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
import okhttp3.Response;
|
|
||||||
|
|
||||||
public class Cam4UpdateService extends PaginatedScheduledService {
|
public class Cam4UpdateService extends PaginatedScheduledService {
|
||||||
|
|
||||||
|
@ -43,7 +41,7 @@ public class Cam4UpdateService extends PaginatedScheduledService {
|
||||||
this.loginRequired = loginRequired;
|
this.loginRequired = loginRequired;
|
||||||
|
|
||||||
ExecutorService executor = Executors.newSingleThreadExecutor(r -> {
|
ExecutorService executor = Executors.newSingleThreadExecutor(r -> {
|
||||||
Thread t = new Thread(r);
|
var t = new Thread(r);
|
||||||
t.setDaemon(true);
|
t.setDaemon(true);
|
||||||
t.setName("ThumbOverviewTab UpdateService");
|
t.setName("ThumbOverviewTab UpdateService");
|
||||||
return t;
|
return t;
|
||||||
|
@ -64,35 +62,14 @@ public class Cam4UpdateService extends PaginatedScheduledService {
|
||||||
if (loginRequired) {
|
if (loginRequired) {
|
||||||
SiteUiFactory.getUi(site).login();
|
SiteUiFactory.getUi(site).login();
|
||||||
}
|
}
|
||||||
Request request = new Request.Builder()
|
var request = new Request.Builder()
|
||||||
.url(pageUrl)
|
.url(pageUrl)
|
||||||
.header(ACCEPT_LANGUAGE, Locale.ENGLISH.getLanguage())
|
.header(ACCEPT_LANGUAGE, Locale.ENGLISH.getLanguage())
|
||||||
.header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent)
|
.header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent)
|
||||||
.build();
|
.build();
|
||||||
try (Response response = site.getHttpClient().execute(request)) {
|
try (var response = site.getHttpClient().execute(request)) {
|
||||||
if (response.isSuccessful()) {
|
if (response.isSuccessful()) {
|
||||||
JSONObject json = new JSONObject(response.body().string());
|
return parseModels(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;
|
|
||||||
} else {
|
} else {
|
||||||
throw new HttpException(response.code(), response.message());
|
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) {
|
public void setUrl(String url) {
|
||||||
this.url = url;
|
this.url = url;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package ctbrec.ui.sites.camsoda;
|
package ctbrec.ui.sites.camsoda;
|
||||||
|
|
||||||
import ctbrec.Config;
|
import ctbrec.Config;
|
||||||
import ctbrec.Settings;
|
|
||||||
import ctbrec.sites.camsoda.Camsoda;
|
import ctbrec.sites.camsoda.Camsoda;
|
||||||
import ctbrec.ui.DesktopIntegration;
|
import ctbrec.ui.DesktopIntegration;
|
||||||
import ctbrec.ui.settings.SettingsTab;
|
import ctbrec.ui.settings.SettingsTab;
|
||||||
|
@ -25,15 +24,15 @@ public class CamsodaConfigUI extends AbstractConfigUI {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Parent createConfigPanel() {
|
public Parent createConfigPanel() {
|
||||||
GridPane layout = SettingsTab.createGridLayout();
|
var layout = SettingsTab.createGridLayout();
|
||||||
Settings settings = Config.getInstance().getSettings();
|
var settings = Config.getInstance().getSettings();
|
||||||
|
|
||||||
int row = 0;
|
var row = 0;
|
||||||
Label l = new Label("Active");
|
var l = new Label("Active");
|
||||||
layout.add(l, 0, row);
|
layout.add(l, 0, row);
|
||||||
CheckBox enabled = new CheckBox();
|
var enabled = new CheckBox();
|
||||||
enabled.setSelected(!settings.disabledSites.contains(camsoda.getName()));
|
enabled.setSelected(!settings.disabledSites.contains(camsoda.getName()));
|
||||||
enabled.setOnAction((e) -> {
|
enabled.setOnAction(e -> {
|
||||||
if(enabled.isSelected()) {
|
if(enabled.isSelected()) {
|
||||||
settings.disabledSites.remove(camsoda.getName());
|
settings.disabledSites.remove(camsoda.getName());
|
||||||
} else {
|
} else {
|
||||||
|
@ -45,7 +44,7 @@ public class CamsodaConfigUI extends AbstractConfigUI {
|
||||||
layout.add(enabled, 1, row++);
|
layout.add(enabled, 1, row++);
|
||||||
|
|
||||||
layout.add(new Label("CamSoda User"), 0, 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) -> {
|
username.textProperty().addListener((ob, o, n) -> {
|
||||||
if(!n.equals(Config.getInstance().getSettings().camsodaUsername)) {
|
if(!n.equals(Config.getInstance().getSettings().camsodaUsername)) {
|
||||||
Config.getInstance().getSettings().camsodaUsername = username.getText();
|
Config.getInstance().getSettings().camsodaUsername = username.getText();
|
||||||
|
@ -59,7 +58,7 @@ public class CamsodaConfigUI extends AbstractConfigUI {
|
||||||
layout.add(username, 1, row++);
|
layout.add(username, 1, row++);
|
||||||
|
|
||||||
layout.add(new Label("CamSoda Password"), 0, row);
|
layout.add(new Label("CamSoda Password"), 0, row);
|
||||||
PasswordField password = new PasswordField();
|
var password = new PasswordField();
|
||||||
password.setText(Config.getInstance().getSettings().camsodaPassword);
|
password.setText(Config.getInstance().getSettings().camsodaPassword);
|
||||||
password.textProperty().addListener((ob, o, n) -> {
|
password.textProperty().addListener((ob, o, n) -> {
|
||||||
if(!n.equals(Config.getInstance().getSettings().camsodaPassword)) {
|
if(!n.equals(Config.getInstance().getSettings().camsodaPassword)) {
|
||||||
|
@ -73,9 +72,9 @@ public class CamsodaConfigUI extends AbstractConfigUI {
|
||||||
GridPane.setColumnSpan(password, 2);
|
GridPane.setColumnSpan(password, 2);
|
||||||
layout.add(password, 1, row++);
|
layout.add(password, 1, row++);
|
||||||
|
|
||||||
Button createAccount = new Button("Create new Account");
|
var createAccount = new Button("Create new Account");
|
||||||
createAccount.setOnAction((e) -> DesktopIntegration.open(camsoda.getAffiliateLink()));
|
createAccount.setOnAction(e -> DesktopIntegration.open(camsoda.getAffiliateLink()));
|
||||||
layout.add(createAccount, 1, row++);
|
layout.add(createAccount, 1, row);
|
||||||
GridPane.setColumnSpan(createAccount, 2);
|
GridPane.setColumnSpan(createAccount, 2);
|
||||||
GridPane.setMargin(username, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
|
GridPane.setMargin(username, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
|
||||||
GridPane.setMargin(password, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
|
GridPane.setMargin(password, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
|
||||||
|
|
|
@ -34,10 +34,10 @@ public class CamsodaFollowedTab extends ThumbOverviewTab implements FollowedTab
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addOnlineOfflineSelector() {
|
private void addOnlineOfflineSelector() {
|
||||||
ToggleGroup group = new ToggleGroup();
|
var group = new ToggleGroup();
|
||||||
RadioButton online = new RadioButton("online");
|
var online = new RadioButton("online");
|
||||||
online.setToggleGroup(group);
|
online.setToggleGroup(group);
|
||||||
RadioButton offline = new RadioButton("offline");
|
var offline = new RadioButton("offline");
|
||||||
offline.setToggleGroup(group);
|
offline.setToggleGroup(group);
|
||||||
pagination.getChildren().add(online);
|
pagination.getChildren().add(online);
|
||||||
pagination.getChildren().add(offline);
|
pagination.getChildren().add(offline);
|
||||||
|
@ -59,7 +59,7 @@ public class CamsodaFollowedTab extends ThumbOverviewTab implements FollowedTab
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onFail(WorkerStateEvent event) {
|
protected void onFail(WorkerStateEvent event) {
|
||||||
String msg = "";
|
var msg = "";
|
||||||
if (event.getSource().getException() != null) {
|
if (event.getSource().getException() != null) {
|
||||||
msg = ": " + event.getSource().getException().getMessage();
|
msg = ": " + event.getSource().getException().getMessage();
|
||||||
}
|
}
|
||||||
|
@ -75,10 +75,8 @@ public class CamsodaFollowedTab extends ThumbOverviewTab implements FollowedTab
|
||||||
|
|
||||||
public void setScene(Scene scene) {
|
public void setScene(Scene scene) {
|
||||||
scene.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
|
scene.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
|
||||||
if (this.isSelected()) {
|
if (this.isSelected() && event.getCode() == KeyCode.DELETE) {
|
||||||
if (event.getCode() == KeyCode.DELETE) {
|
follow(selectedThumbCells, false);
|
||||||
follow(selectedThumbCells, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,13 +8,12 @@ import java.time.ZoneId;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.time.format.FormatStyle;
|
import java.time.format.FormatStyle;
|
||||||
import java.time.temporal.TemporalAccessor;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -69,7 +68,7 @@ public class CamsodaShowsTab extends Tab implements TabSelectionListener {
|
||||||
showList.setPadding(new Insets(5));
|
showList.setPadding(new Insets(5));
|
||||||
showList.setHgap(5);
|
showList.setHgap(5);
|
||||||
showList.setVgap(5);
|
showList.setVgap(5);
|
||||||
ProgressIndicator progressIndicator = new ProgressIndicator();
|
var progressIndicator = new ProgressIndicator();
|
||||||
progressIndicator.setPrefSize(100, 100);
|
progressIndicator.setPrefSize(100, 100);
|
||||||
setContent(progressIndicator);
|
setContent(progressIndicator);
|
||||||
setClosable(false);
|
setClosable(false);
|
||||||
|
@ -81,41 +80,7 @@ public class CamsodaShowsTab extends Tab implements TabSelectionListener {
|
||||||
Task<List<ShowBox>> task = new Task<List<ShowBox>>() {
|
Task<List<ShowBox>> task = new Task<List<ShowBox>>() {
|
||||||
@Override
|
@Override
|
||||||
protected List<ShowBox> call() throws Exception {
|
protected List<ShowBox> call() throws Exception {
|
||||||
String url = camsoda.getBaseUrl() + "/api/v1/user/model_shows";
|
return loadShows();
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -125,11 +90,14 @@ public class CamsodaShowsTab extends Tab implements TabSelectionListener {
|
||||||
try {
|
try {
|
||||||
List<ShowBox> boxes = get();
|
List<ShowBox> boxes = get();
|
||||||
showList.getChildren().clear();
|
showList.getChildren().clear();
|
||||||
int index = 0;
|
var index = 0;
|
||||||
for (ShowBox showBox : boxes) {
|
for (ShowBox showBox : boxes) {
|
||||||
showList.add(showBox, index % 2, index++ / 2);
|
showList.add(showBox, index % 2, index++ / 2);
|
||||||
GridPane.setMargin(showBox, new Insets(20, 20, 0, 20));
|
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) {
|
} catch (Exception e) {
|
||||||
LOG.error("Couldn't load upcoming camsoda shows", e);
|
LOG.error("Couldn't load upcoming camsoda shows", e);
|
||||||
}
|
}
|
||||||
|
@ -140,6 +108,44 @@ public class CamsodaShowsTab extends Tab implements TabSelectionListener {
|
||||||
GlobalThreadPool.submit(task);
|
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
|
@Override
|
||||||
public void deselected() {
|
public void deselected() {
|
||||||
// nothing to do
|
// nothing to do
|
||||||
|
@ -165,31 +171,31 @@ public class CamsodaShowsTab extends Tab implements TabSelectionListener {
|
||||||
setPrefHeight(268);
|
setPrefHeight(268);
|
||||||
setContent(root);
|
setContent(root);
|
||||||
|
|
||||||
ImageView thumb = new ImageView();
|
var thumb = new ImageView();
|
||||||
thumb.setPreserveRatio(true);
|
thumb.setPreserveRatio(true);
|
||||||
thumb.setFitHeight(thumbSize);
|
thumb.setFitHeight(thumbSize);
|
||||||
loadImage(model, thumb);
|
loadImage(model, thumb);
|
||||||
root.setLeft(new ProgressIndicator());
|
root.setLeft(new ProgressIndicator());
|
||||||
BorderPane.setMargin(thumb, new Insets(10, 30, 10, 10));
|
BorderPane.setMargin(thumb, new Insets(10, 30, 10, 10));
|
||||||
|
|
||||||
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM, FormatStyle.MEDIUM);
|
var formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM, FormatStyle.MEDIUM);
|
||||||
GridPane grid = new GridPane();
|
var grid = new GridPane();
|
||||||
|
|
||||||
grid.add(createLabel("Start", true), 0, 0);
|
grid.add(createLabel("Start", true), 0, 0);
|
||||||
grid.add(createLabel(formatter.format(startTime), false), 1, 0);
|
grid.add(createLabel(formatter.format(startTime), false), 1, 0);
|
||||||
grid.add(createLabel("End", true), 0, 1);
|
grid.add(createLabel("End", true), 0, 1);
|
||||||
grid.add(createLabel(formatter.format(endTime), false), 1, 1);
|
grid.add(createLabel(formatter.format(endTime), false), 1, 1);
|
||||||
Button record = new Button("Record Model");
|
var recordButton = new Button("Record Model");
|
||||||
record.setTooltip(new Tooltip(record.getText()));
|
recordButton.setTooltip(new Tooltip(recordButton.getText()));
|
||||||
record.setOnAction(evt -> record(model));
|
recordButton.setOnAction(evt -> recordModel(model));
|
||||||
grid.add(record, 1, 2);
|
grid.add(recordButton, 1, 2);
|
||||||
GridPane.setMargin(record, new Insets(10));
|
GridPane.setMargin(recordButton, new Insets(10));
|
||||||
Button follow = new Button("Follow");
|
var follow = new Button("Follow");
|
||||||
follow.setTooltip(new Tooltip(follow.getText()));
|
follow.setTooltip(new Tooltip(follow.getText()));
|
||||||
follow.setOnAction(evt -> follow(model));
|
follow.setOnAction(evt -> follow(model));
|
||||||
grid.add(follow, 1, 3);
|
grid.add(follow, 1, 3);
|
||||||
GridPane.setMargin(follow, new Insets(10));
|
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.setTooltip(new Tooltip(openInBrowser.getText()));
|
||||||
openInBrowser.setOnAction(evt -> DesktopIntegration.open(model.getUrl()));
|
openInBrowser.setOnAction(evt -> DesktopIntegration.open(model.getUrl()));
|
||||||
grid.add(openInBrowser, 1, 4);
|
grid.add(openInBrowser, 1, 4);
|
||||||
|
@ -197,7 +203,7 @@ public class CamsodaShowsTab extends Tab implements TabSelectionListener {
|
||||||
root.setCenter(grid);
|
root.setCenter(grid);
|
||||||
loadImage(model, thumb);
|
loadImage(model, thumb);
|
||||||
|
|
||||||
record.minWidthProperty().bind(openInBrowser.widthProperty());
|
recordButton.minWidthProperty().bind(openInBrowser.widthProperty());
|
||||||
follow.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);
|
setCursor(Cursor.WAIT);
|
||||||
GlobalThreadPool.submit(() -> {
|
GlobalThreadPool.submit(() -> {
|
||||||
try {
|
try {
|
||||||
|
@ -233,47 +239,56 @@ public class CamsodaShowsTab extends Tab implements TabSelectionListener {
|
||||||
GlobalThreadPool.submit(() -> {
|
GlobalThreadPool.submit(() -> {
|
||||||
try {
|
try {
|
||||||
String url = camsoda.getBaseUrl() + "/api/v1/user/" + model.getName();
|
String url = camsoda.getBaseUrl() + "/api/v1/user/" + model.getName();
|
||||||
Request detailRequest = new Request.Builder().url(url).build();
|
var detailRequest = new Request.Builder().url(url).build();
|
||||||
Response resp = camsoda.getHttpClient().execute(detailRequest);
|
try (Response resp = camsoda.getHttpClient().execute(detailRequest)) {
|
||||||
if (resp.isSuccessful()) {
|
if (resp.isSuccessful()) {
|
||||||
JSONObject json = new JSONObject(resp.body().string());
|
parseImageUrl(resp.body().string()).ifPresent(imageUrl -> updateImageView(thumb, imageUrl));
|
||||||
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);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
resp.close();
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOG.error("Couldn't load model details", 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) {
|
private Node createLabel(String string, boolean bold) {
|
||||||
Label label = new Label(string);
|
var label = new Label(string);
|
||||||
label.setPadding(new Insets(10));
|
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));
|
label.setFont(Font.font(def.getFamily(), bold ? FontWeight.BOLD : FontWeight.NORMAL, 16));
|
||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,58 +34,4 @@ public class CamsodaSiteUi extends AbstractSiteUi {
|
||||||
boolean automaticLogin = camsoda.login();
|
boolean automaticLogin = camsoda.login();
|
||||||
return automaticLogin;
|
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);
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ import ctbrec.ui.tabs.ThumbOverviewTab;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
import javafx.scene.control.Tab;
|
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 static final String API_URL = BASE_URI + "/api/v1/browse/online";
|
||||||
private Camsoda camsoda;
|
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("Male", API_URL, m -> Objects.equals("m", m.getGender())));
|
||||||
tabs.add(createTab("Couples", API_URL, m -> Objects.equals("c", 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("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.setRecorder(recorder);
|
||||||
followedTab.setScene(scene);
|
followedTab.setScene(scene);
|
||||||
tabs.add(followedTab);
|
tabs.add(followedTab);
|
||||||
|
@ -51,8 +50,8 @@ public class CamsodaTabProvider extends TabProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Tab createTab(String title, String url, Predicate<CamsodaModel> filter) {
|
private Tab createTab(String title, String url, Predicate<CamsodaModel> filter) {
|
||||||
CamsodaUpdateService updateService = new CamsodaUpdateService(url, false, camsoda, filter);
|
var updateService = new CamsodaUpdateService(url, false, camsoda, filter);
|
||||||
ThumbOverviewTab tab = new ThumbOverviewTab(title, updateService, camsoda);
|
var tab = new ThumbOverviewTab(title, updateService, camsoda);
|
||||||
tab.setRecorder(recorder);
|
tab.setRecorder(recorder);
|
||||||
return tab;
|
return tab;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,6 @@ import ctbrec.ui.SiteUiFactory;
|
||||||
import ctbrec.ui.tabs.PaginatedScheduledService;
|
import ctbrec.ui.tabs.PaginatedScheduledService;
|
||||||
import javafx.concurrent.Task;
|
import javafx.concurrent.Task;
|
||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
import okhttp3.Response;
|
|
||||||
|
|
||||||
public class CamsodaUpdateService extends PaginatedScheduledService {
|
public class CamsodaUpdateService extends PaginatedScheduledService {
|
||||||
|
|
||||||
|
@ -53,7 +52,7 @@ public class CamsodaUpdateService extends PaginatedScheduledService {
|
||||||
return loadOnlineModels().stream()
|
return loadOnlineModels().stream()
|
||||||
.sorted((m1,m2) -> (int)(m2.getSortOrder() - m1.getSortOrder()))
|
.sorted((m1,m2) -> (int)(m2.getSortOrder() - m1.getSortOrder()))
|
||||||
.filter(filter)
|
.filter(filter)
|
||||||
.skip( (page-1) * modelsPerPage)
|
.skip( (page-1) * (long)modelsPerPage)
|
||||||
.limit(modelsPerPage)
|
.limit(modelsPerPage)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
@ -61,71 +60,17 @@ public class CamsodaUpdateService extends PaginatedScheduledService {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected List<CamsodaModel> loadOnlineModels() throws IOException {
|
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();
|
return Collections.emptyList();
|
||||||
} else {
|
} else {
|
||||||
LOG.debug("Fetching page {}", url);
|
LOG.debug("Fetching page {}", url);
|
||||||
if(loginRequired) {
|
if (loginRequired) {
|
||||||
SiteUiFactory.getUi(camsoda).login();
|
SiteUiFactory.getUi(camsoda).login();
|
||||||
}
|
}
|
||||||
Request request = new Request.Builder().url(url).build();
|
var request = new Request.Builder().url(url).build();
|
||||||
try (Response response = camsoda.getHttpClient().execute(request)) {
|
try (var response = camsoda.getHttpClient().execute(request)) {
|
||||||
if (response.isSuccessful()) {
|
if (response.isSuccessful()) {
|
||||||
String body = response.body().string();
|
return parseModels(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;
|
|
||||||
} else {
|
} else {
|
||||||
throw new HttpException(response.code(), response.message());
|
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) {
|
private int getTemplateIndex(JSONArray template, String string) {
|
||||||
for (int i = 0; i < template.length(); i++) {
|
for (var i = 0; i < template.length(); i++) {
|
||||||
String s = template.getString(i);
|
var s = template.getString(i);
|
||||||
if(Objects.equals(s, string)) {
|
if (Objects.equals(s, string)) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package ctbrec.ui.sites.chaturbate;
|
package ctbrec.ui.sites.chaturbate;
|
||||||
|
|
||||||
import ctbrec.Config;
|
import ctbrec.Config;
|
||||||
import ctbrec.Settings;
|
|
||||||
import ctbrec.sites.chaturbate.Chaturbate;
|
import ctbrec.sites.chaturbate.Chaturbate;
|
||||||
import ctbrec.ui.DesktopIntegration;
|
import ctbrec.ui.DesktopIntegration;
|
||||||
import ctbrec.ui.settings.SettingsTab;
|
import ctbrec.ui.settings.SettingsTab;
|
||||||
|
@ -25,15 +24,15 @@ public class ChaturbateConfigUi extends AbstractConfigUI {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Parent createConfigPanel() {
|
public Parent createConfigPanel() {
|
||||||
Settings settings = Config.getInstance().getSettings();
|
var settings = Config.getInstance().getSettings();
|
||||||
GridPane layout = SettingsTab.createGridLayout();
|
GridPane layout = SettingsTab.createGridLayout();
|
||||||
|
|
||||||
int row = 0;
|
var row = 0;
|
||||||
Label l = new Label("Active");
|
var l = new Label("Active");
|
||||||
layout.add(l, 0, row);
|
layout.add(l, 0, row);
|
||||||
CheckBox enabled = new CheckBox();
|
var enabled = new CheckBox();
|
||||||
enabled.setSelected(!settings.disabledSites.contains(chaturbate.getName()));
|
enabled.setSelected(!settings.disabledSites.contains(chaturbate.getName()));
|
||||||
enabled.setOnAction((e) -> {
|
enabled.setOnAction(e -> {
|
||||||
if(enabled.isSelected()) {
|
if(enabled.isSelected()) {
|
||||||
settings.disabledSites.remove(chaturbate.getName());
|
settings.disabledSites.remove(chaturbate.getName());
|
||||||
} else {
|
} else {
|
||||||
|
@ -45,7 +44,7 @@ public class ChaturbateConfigUi extends AbstractConfigUI {
|
||||||
layout.add(enabled, 1, row++);
|
layout.add(enabled, 1, row++);
|
||||||
|
|
||||||
layout.add(new Label("Chaturbate User"), 0, 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) -> {
|
username.textProperty().addListener((ob, o, n) -> {
|
||||||
if(!n.equals(Config.getInstance().getSettings().chaturbateUsername)) {
|
if(!n.equals(Config.getInstance().getSettings().chaturbateUsername)) {
|
||||||
Config.getInstance().getSettings().chaturbateUsername = n;
|
Config.getInstance().getSettings().chaturbateUsername = n;
|
||||||
|
@ -59,7 +58,7 @@ public class ChaturbateConfigUi extends AbstractConfigUI {
|
||||||
layout.add(username, 1, row++);
|
layout.add(username, 1, row++);
|
||||||
|
|
||||||
layout.add(new Label("Chaturbate Password"), 0, row);
|
layout.add(new Label("Chaturbate Password"), 0, row);
|
||||||
PasswordField password = new PasswordField();
|
var password = new PasswordField();
|
||||||
password.setText(Config.getInstance().getSettings().chaturbatePassword);
|
password.setText(Config.getInstance().getSettings().chaturbatePassword);
|
||||||
password.textProperty().addListener((ob, o, n) -> {
|
password.textProperty().addListener((ob, o, n) -> {
|
||||||
if(!n.equals(Config.getInstance().getSettings().chaturbatePassword)) {
|
if(!n.equals(Config.getInstance().getSettings().chaturbatePassword)) {
|
||||||
|
@ -74,7 +73,7 @@ public class ChaturbateConfigUi extends AbstractConfigUI {
|
||||||
layout.add(password, 1, row++);
|
layout.add(password, 1, row++);
|
||||||
|
|
||||||
layout.add(new Label("Chaturbate Base URL"), 0, 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.setText(Config.getInstance().getSettings().chaturbateBaseUrl);
|
||||||
baseUrl.textProperty().addListener((ob, o, n) -> {
|
baseUrl.textProperty().addListener((ob, o, n) -> {
|
||||||
Config.getInstance().getSettings().chaturbateBaseUrl = baseUrl.getText();
|
Config.getInstance().getSettings().chaturbateBaseUrl = baseUrl.getText();
|
||||||
|
@ -85,9 +84,9 @@ public class ChaturbateConfigUi extends AbstractConfigUI {
|
||||||
GridPane.setColumnSpan(baseUrl, 2);
|
GridPane.setColumnSpan(baseUrl, 2);
|
||||||
layout.add(baseUrl, 1, row++);
|
layout.add(baseUrl, 1, row++);
|
||||||
|
|
||||||
Button createAccount = new Button("Create new Account");
|
var createAccount = new Button("Create new Account");
|
||||||
createAccount.setOnAction((e) -> DesktopIntegration.open(Chaturbate.REGISTRATION_LINK));
|
createAccount.setOnAction(e -> DesktopIntegration.open(Chaturbate.REGISTRATION_LINK));
|
||||||
layout.add(createAccount, 1, row++);
|
layout.add(createAccount, 1, row);
|
||||||
GridPane.setColumnSpan(createAccount, 2);
|
GridPane.setColumnSpan(createAccount, 2);
|
||||||
GridPane.setMargin(username, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
|
GridPane.setMargin(username, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
|
||||||
GridPane.setMargin(password, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
|
GridPane.setMargin(password, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
|
||||||
|
|
|
@ -34,17 +34,17 @@ public class ChaturbateFollowedTab extends ThumbOverviewTab implements FollowedT
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addOnlineOfflineSelector() {
|
private void addOnlineOfflineSelector() {
|
||||||
ToggleGroup group = new ToggleGroup();
|
var group = new ToggleGroup();
|
||||||
RadioButton online = new RadioButton("online");
|
var online = new RadioButton("online");
|
||||||
online.setToggleGroup(group);
|
online.setToggleGroup(group);
|
||||||
RadioButton offline = new RadioButton("offline");
|
var offline = new RadioButton("offline");
|
||||||
offline.setToggleGroup(group);
|
offline.setToggleGroup(group);
|
||||||
pagination.getChildren().add(online);
|
pagination.getChildren().add(online);
|
||||||
pagination.getChildren().add(offline);
|
pagination.getChildren().add(offline);
|
||||||
HBox.setMargin(online, new Insets(5,5,5,40));
|
HBox.setMargin(online, new Insets(5,5,5,40));
|
||||||
HBox.setMargin(offline, new Insets(5,5,5,5));
|
HBox.setMargin(offline, new Insets(5,5,5,5));
|
||||||
online.setSelected(true);
|
online.setSelected(true);
|
||||||
group.selectedToggleProperty().addListener((e) -> {
|
group.selectedToggleProperty().addListener(e -> {
|
||||||
if(online.isSelected()) {
|
if(online.isSelected()) {
|
||||||
((ChaturbateUpdateService)updateService).setUrl(onlineUrl);
|
((ChaturbateUpdateService)updateService).setUrl(onlineUrl);
|
||||||
} else {
|
} else {
|
||||||
|
@ -75,10 +75,8 @@ public class ChaturbateFollowedTab extends ThumbOverviewTab implements FollowedT
|
||||||
|
|
||||||
public void setScene(Scene scene) {
|
public void setScene(Scene scene) {
|
||||||
scene.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
|
scene.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
|
||||||
if(this.isSelected()) {
|
if (this.isSelected() && event.getCode() == KeyCode.DELETE) {
|
||||||
if(event.getCode() == KeyCode.DELETE) {
|
follow(selectedThumbCells, false);
|
||||||
follow(selectedThumbCells, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import ctbrec.ui.tabs.ThumbOverviewTab;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
import javafx.scene.control.Tab;
|
import javafx.scene.control.Tab;
|
||||||
|
|
||||||
public class ChaturbateTabProvider extends TabProvider {
|
public class ChaturbateTabProvider implements TabProvider {
|
||||||
|
|
||||||
private Chaturbate chaturbate;
|
private Chaturbate chaturbate;
|
||||||
private Recorder recorder;
|
private Recorder recorder;
|
||||||
|
@ -44,8 +44,8 @@ public class ChaturbateTabProvider extends TabProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Tab createTab(String title, String url) {
|
private Tab createTab(String title, String url) {
|
||||||
ChaturbateUpdateService updateService = new ChaturbateUpdateService(url, false, chaturbate);
|
var updateService = new ChaturbateUpdateService(url, false, chaturbate);
|
||||||
ThumbOverviewTab tab = new ThumbOverviewTab(title, updateService, chaturbate);
|
var tab = new ThumbOverviewTab(title, updateService, chaturbate);
|
||||||
tab.setRecorder(recorder);
|
tab.setRecorder(recorder);
|
||||||
tab.setImageAspectRatio(9.0 / 16.0);
|
tab.setImageAspectRatio(9.0 / 16.0);
|
||||||
return tab;
|
return tab;
|
||||||
|
|
|
@ -16,7 +16,6 @@ import ctbrec.ui.SiteUiFactory;
|
||||||
import ctbrec.ui.tabs.PaginatedScheduledService;
|
import ctbrec.ui.tabs.PaginatedScheduledService;
|
||||||
import javafx.concurrent.Task;
|
import javafx.concurrent.Task;
|
||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
import okhttp3.Response;
|
|
||||||
|
|
||||||
public class ChaturbateUpdateService extends PaginatedScheduledService {
|
public class ChaturbateUpdateService extends PaginatedScheduledService {
|
||||||
|
|
||||||
|
@ -31,7 +30,7 @@ public class ChaturbateUpdateService extends PaginatedScheduledService {
|
||||||
this.chaturbate = chaturbate;
|
this.chaturbate = chaturbate;
|
||||||
|
|
||||||
ExecutorService executor = Executors.newSingleThreadExecutor(r -> {
|
ExecutorService executor = Executors.newSingleThreadExecutor(r -> {
|
||||||
Thread t = new Thread(r);
|
var t = new Thread(r);
|
||||||
t.setDaemon(true);
|
t.setDaemon(true);
|
||||||
t.setName("ThumbOverviewTab UpdateService");
|
t.setName("ThumbOverviewTab UpdateService");
|
||||||
return t;
|
return t;
|
||||||
|
@ -44,7 +43,7 @@ public class ChaturbateUpdateService extends PaginatedScheduledService {
|
||||||
return new Task<List<Model>>() {
|
return new Task<List<Model>>() {
|
||||||
@Override
|
@Override
|
||||||
public List<Model> call() throws IOException {
|
public List<Model> call() throws IOException {
|
||||||
if(loginRequired && !chaturbate.credentialsAvailable()) {
|
if (loginRequired && !chaturbate.credentialsAvailable()) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
} else {
|
} else {
|
||||||
String pageUrl = ChaturbateUpdateService.this.url + "?page="+page+"&keywords=&_=" + System.currentTimeMillis();
|
String pageUrl = ChaturbateUpdateService.this.url + "?page="+page+"&keywords=&_=" + System.currentTimeMillis();
|
||||||
|
@ -52,16 +51,15 @@ public class ChaturbateUpdateService extends PaginatedScheduledService {
|
||||||
if(loginRequired) {
|
if(loginRequired) {
|
||||||
SiteUiFactory.getUi(chaturbate).login();
|
SiteUiFactory.getUi(chaturbate).login();
|
||||||
}
|
}
|
||||||
Request request = new Request.Builder().url(pageUrl).build();
|
var request = new Request.Builder().url(pageUrl).build();
|
||||||
Response response = chaturbate.getHttpClient().execute(request);
|
try (var response = chaturbate.getHttpClient().execute(request)) {
|
||||||
if (response.isSuccessful()) {
|
if (response.isSuccessful()) {
|
||||||
List<Model> models = ChaturbateModelParser.parseModels(chaturbate, response.body().string());
|
List<Model> models = ChaturbateModelParser.parseModels(chaturbate, response.body().string());
|
||||||
response.close();
|
return models;
|
||||||
return models;
|
} else {
|
||||||
} else {
|
int code = response.code();
|
||||||
int code = response.code();
|
throw new IOException("HTTP status " + code);
|
||||||
response.close();
|
}
|
||||||
throw new IOException("HTTP status " + code);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,25 +14,19 @@ public class Fc2FollowedTab extends ThumbOverviewTab implements FollowedTab {
|
||||||
super("Followed", new Fc2FollowedUpdateService(fc2live), fc2live);
|
super("Followed", new Fc2FollowedUpdateService(fc2live), fc2live);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void createGui() {
|
|
||||||
super.createGui();
|
|
||||||
//addOnlineOfflineSelector();
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
private void addOnlineOfflineSelector() {
|
private void addOnlineOfflineSelector() {
|
||||||
ToggleGroup group = new ToggleGroup();
|
var group = new ToggleGroup();
|
||||||
RadioButton online = new RadioButton("online");
|
var online = new RadioButton("online");
|
||||||
online.setToggleGroup(group);
|
online.setToggleGroup(group);
|
||||||
RadioButton offline = new RadioButton("offline");
|
var offline = new RadioButton("offline");
|
||||||
offline.setToggleGroup(group);
|
offline.setToggleGroup(group);
|
||||||
pagination.getChildren().add(online);
|
pagination.getChildren().add(online);
|
||||||
pagination.getChildren().add(offline);
|
pagination.getChildren().add(offline);
|
||||||
HBox.setMargin(online, new Insets(5,5,5,40));
|
HBox.setMargin(online, new Insets(5,5,5,40));
|
||||||
HBox.setMargin(offline, new Insets(5,5,5,5));
|
HBox.setMargin(offline, new Insets(5,5,5,5));
|
||||||
online.setSelected(true);
|
online.setSelected(true);
|
||||||
group.selectedToggleProperty().addListener((e) -> {
|
group.selectedToggleProperty().addListener(e -> {
|
||||||
((Fc2FollowedUpdateService)updateService).setShowOnline(online.isSelected());
|
((Fc2FollowedUpdateService)updateService).setShowOnline(online.isSelected());
|
||||||
queue.clear();
|
queue.clear();
|
||||||
updateService.restart();
|
updateService.restart();
|
||||||
|
|
|
@ -6,7 +6,6 @@ import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import ctbrec.Config;
|
import ctbrec.Config;
|
||||||
|
@ -34,54 +33,58 @@ public class Fc2FollowedUpdateService extends PaginatedScheduledService {
|
||||||
return new Task<List<Model>>() {
|
return new Task<List<Model>>() {
|
||||||
@Override
|
@Override
|
||||||
public List<Model> call() throws IOException {
|
public List<Model> call() throws IOException {
|
||||||
if(!fc2live.login()) {
|
return loadModels();
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setShowOnline(boolean online) {
|
private List<Model> loadModels() throws IOException {
|
||||||
//this.online = online;
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package ctbrec.ui.sites.fc2live;
|
package ctbrec.ui.sites.fc2live;
|
||||||
|
|
||||||
import ctbrec.Config;
|
import ctbrec.Config;
|
||||||
import ctbrec.Settings;
|
|
||||||
import ctbrec.sites.fc2live.Fc2Live;
|
import ctbrec.sites.fc2live.Fc2Live;
|
||||||
import ctbrec.ui.DesktopIntegration;
|
import ctbrec.ui.DesktopIntegration;
|
||||||
import ctbrec.ui.settings.SettingsTab;
|
import ctbrec.ui.settings.SettingsTab;
|
||||||
|
@ -25,15 +24,15 @@ public class Fc2LiveConfigUI extends AbstractConfigUI {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Parent createConfigPanel() {
|
public Parent createConfigPanel() {
|
||||||
GridPane layout = SettingsTab.createGridLayout();
|
var layout = SettingsTab.createGridLayout();
|
||||||
Settings settings = Config.getInstance().getSettings();
|
var settings = Config.getInstance().getSettings();
|
||||||
|
|
||||||
int row = 0;
|
var row = 0;
|
||||||
Label l = new Label("Active");
|
var l = new Label("Active");
|
||||||
layout.add(l, 0, row);
|
layout.add(l, 0, row);
|
||||||
CheckBox enabled = new CheckBox();
|
var enabled = new CheckBox();
|
||||||
enabled.setSelected(!settings.disabledSites.contains(fc2live.getName()));
|
enabled.setSelected(!settings.disabledSites.contains(fc2live.getName()));
|
||||||
enabled.setOnAction((e) -> {
|
enabled.setOnAction(e -> {
|
||||||
if(enabled.isSelected()) {
|
if(enabled.isSelected()) {
|
||||||
settings.disabledSites.remove(fc2live.getName());
|
settings.disabledSites.remove(fc2live.getName());
|
||||||
} else {
|
} else {
|
||||||
|
@ -45,7 +44,7 @@ public class Fc2LiveConfigUI extends AbstractConfigUI {
|
||||||
layout.add(enabled, 1, row++);
|
layout.add(enabled, 1, row++);
|
||||||
|
|
||||||
layout.add(new Label("FC2Live User"), 0, 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) -> {
|
username.textProperty().addListener((ob, o, n) -> {
|
||||||
if(!n.equals(Config.getInstance().getSettings().fc2liveUsername)) {
|
if(!n.equals(Config.getInstance().getSettings().fc2liveUsername)) {
|
||||||
Config.getInstance().getSettings().fc2liveUsername = username.getText();
|
Config.getInstance().getSettings().fc2liveUsername = username.getText();
|
||||||
|
@ -59,7 +58,7 @@ public class Fc2LiveConfigUI extends AbstractConfigUI {
|
||||||
layout.add(username, 1, row++);
|
layout.add(username, 1, row++);
|
||||||
|
|
||||||
layout.add(new Label("FC2Live Password"), 0, row);
|
layout.add(new Label("FC2Live Password"), 0, row);
|
||||||
PasswordField password = new PasswordField();
|
var password = new PasswordField();
|
||||||
password.setText(settings.fc2livePassword);
|
password.setText(settings.fc2livePassword);
|
||||||
password.textProperty().addListener((ob, o, n) -> {
|
password.textProperty().addListener((ob, o, n) -> {
|
||||||
if(!n.equals(Config.getInstance().getSettings().fc2livePassword)) {
|
if(!n.equals(Config.getInstance().getSettings().fc2livePassword)) {
|
||||||
|
@ -73,9 +72,9 @@ public class Fc2LiveConfigUI extends AbstractConfigUI {
|
||||||
GridPane.setColumnSpan(password, 2);
|
GridPane.setColumnSpan(password, 2);
|
||||||
layout.add(password, 1, row++);
|
layout.add(password, 1, row++);
|
||||||
|
|
||||||
Button createAccount = new Button("Create new Account");
|
var createAccount = new Button("Create new Account");
|
||||||
createAccount.setOnAction((e) -> DesktopIntegration.open(fc2live.getAffiliateLink()));
|
createAccount.setOnAction(e -> DesktopIntegration.open(fc2live.getAffiliateLink()));
|
||||||
layout.add(createAccount, 1, row++);
|
layout.add(createAccount, 1, row);
|
||||||
GridPane.setColumnSpan(createAccount, 2);
|
GridPane.setColumnSpan(createAccount, 2);
|
||||||
GridPane.setMargin(username, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
|
GridPane.setMargin(username, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
|
||||||
GridPane.setMargin(password, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
|
GridPane.setMargin(password, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
|
||||||
|
|
|
@ -9,7 +9,7 @@ import ctbrec.ui.tabs.ThumbOverviewTab;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
import javafx.scene.control.Tab;
|
import javafx.scene.control.Tab;
|
||||||
|
|
||||||
public class Fc2TabProvider extends TabProvider {
|
public class Fc2TabProvider implements TabProvider {
|
||||||
|
|
||||||
private Fc2Live fc2live;
|
private Fc2Live fc2live;
|
||||||
private Fc2FollowedTab followed;
|
private Fc2FollowedTab followed;
|
||||||
|
@ -31,8 +31,8 @@ public class Fc2TabProvider extends TabProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Tab createTab(String title, String url) {
|
private Tab createTab(String title, String url) {
|
||||||
Fc2UpdateService updateService = new Fc2UpdateService(url, fc2live);
|
var updateService = new Fc2UpdateService(url, fc2live);
|
||||||
ThumbOverviewTab tab = new ThumbOverviewTab(title, updateService, fc2live);
|
var tab = new ThumbOverviewTab(title, updateService, fc2live);
|
||||||
tab.setRecorder(fc2live.getRecorder());
|
tab.setRecorder(fc2live.getRecorder());
|
||||||
return tab;
|
return tab;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@ import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -22,7 +21,6 @@ import ctbrec.ui.tabs.PaginatedScheduledService;
|
||||||
import javafx.concurrent.Task;
|
import javafx.concurrent.Task;
|
||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
import okhttp3.RequestBody;
|
import okhttp3.RequestBody;
|
||||||
import okhttp3.Response;
|
|
||||||
|
|
||||||
public class Fc2UpdateService extends PaginatedScheduledService {
|
public class Fc2UpdateService extends PaginatedScheduledService {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(Fc2UpdateService.class);
|
private static final Logger LOG = LoggerFactory.getLogger(Fc2UpdateService.class);
|
||||||
|
@ -41,7 +39,7 @@ public class Fc2UpdateService extends PaginatedScheduledService {
|
||||||
return new Task<List<Model>>() {
|
return new Task<List<Model>>() {
|
||||||
@Override
|
@Override
|
||||||
public List<Model> call() throws IOException {
|
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()
|
Request req = new Request.Builder()
|
||||||
.url(url)
|
.url(url)
|
||||||
.method("POST", body)
|
.method("POST", body)
|
||||||
|
@ -52,31 +50,31 @@ public class Fc2UpdateService extends PaginatedScheduledService {
|
||||||
.header(X_REQUESTED_WITH, XML_HTTP_REQUEST)
|
.header(X_REQUESTED_WITH, XML_HTTP_REQUEST)
|
||||||
.build();
|
.build();
|
||||||
LOG.debug("Fetching page {}", url);
|
LOG.debug("Fetching page {}", url);
|
||||||
try(Response resp = fc2live.getHttpClient().execute(req)) {
|
try (var resp = fc2live.getHttpClient().execute(req)) {
|
||||||
if(resp.isSuccessful()) {
|
if (resp.isSuccessful()) {
|
||||||
List<Fc2Model> models = new ArrayList<>();
|
List<Fc2Model> models = new ArrayList<>();
|
||||||
String msg = resp.body().string();
|
var msg = resp.body().string();
|
||||||
JSONObject json = new JSONObject(msg);
|
var json = new JSONObject(msg);
|
||||||
JSONArray channels = json.getJSONArray("channel");
|
var channels = json.getJSONArray("channel");
|
||||||
for (int i = 0; i < channels.length(); i++) {
|
for (var i = 0; i < channels.length(); i++) {
|
||||||
JSONObject channel = channels.getJSONObject(i);
|
var channel = channels.getJSONObject(i);
|
||||||
Fc2Model model = (Fc2Model) fc2live.createModel(channel.getString("name"));
|
Fc2Model model = (Fc2Model) fc2live.createModel(channel.getString("name"));
|
||||||
model.setId(channel.getString("id"));
|
model.setId(channel.getString("id"));
|
||||||
model.setUrl(Fc2Live.BASE_URL + '/' + model.getId());
|
model.setUrl(Fc2Live.BASE_URL + '/' + model.getId());
|
||||||
String previewUrl = channel.getString("image");
|
var previewUrl = channel.getString("image");
|
||||||
if(previewUrl == null || previewUrl.trim().isEmpty()) {
|
if (previewUrl == null || previewUrl.trim().isEmpty()) {
|
||||||
previewUrl = getClass().getResource("/image_not_found.png").toString();
|
previewUrl = getClass().getResource("/image_not_found.png").toString();
|
||||||
}
|
}
|
||||||
model.setPreview(previewUrl);
|
model.setPreview(previewUrl);
|
||||||
model.setDescription(channel.optString("title"));
|
model.setDescription(channel.optString("title"));
|
||||||
model.setViewerCount(channel.optInt("count"));
|
model.setViewerCount(channel.optInt("count"));
|
||||||
if(channel.getInt("login") == 0) {
|
if (channel.getInt("login") == 0) {
|
||||||
models.add(model);
|
models.add(model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return models.stream()
|
return models.stream()
|
||||||
.sorted((m1, m2) -> m2.getViewerCount() - m1.getViewerCount())
|
.sorted((m1, m2) -> m2.getViewerCount() - m1.getViewerCount())
|
||||||
.skip( (long)(page - 1) * modelsPerPage)
|
.skip((long) (page - 1) * modelsPerPage)
|
||||||
.limit(modelsPerPage)
|
.limit(modelsPerPage)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package ctbrec.ui.sites.flirt4free;
|
package ctbrec.ui.sites.flirt4free;
|
||||||
|
|
||||||
import ctbrec.Config;
|
import ctbrec.Config;
|
||||||
import ctbrec.Settings;
|
|
||||||
import ctbrec.sites.flirt4free.Flirt4Free;
|
import ctbrec.sites.flirt4free.Flirt4Free;
|
||||||
import ctbrec.ui.DesktopIntegration;
|
import ctbrec.ui.DesktopIntegration;
|
||||||
import ctbrec.ui.settings.SettingsTab;
|
import ctbrec.ui.settings.SettingsTab;
|
||||||
|
@ -25,15 +24,15 @@ public class Flirt4FreeConfigUI extends AbstractConfigUI {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Parent createConfigPanel() {
|
public Parent createConfigPanel() {
|
||||||
GridPane layout = SettingsTab.createGridLayout();
|
var layout = SettingsTab.createGridLayout();
|
||||||
Settings settings = Config.getInstance().getSettings();
|
var settings = Config.getInstance().getSettings();
|
||||||
|
|
||||||
int row = 0;
|
var row = 0;
|
||||||
Label l = new Label("Active");
|
var l = new Label("Active");
|
||||||
layout.add(l, 0, row);
|
layout.add(l, 0, row);
|
||||||
CheckBox enabled = new CheckBox();
|
var enabled = new CheckBox();
|
||||||
enabled.setSelected(!settings.disabledSites.contains(flirt4free.getName()));
|
enabled.setSelected(!settings.disabledSites.contains(flirt4free.getName()));
|
||||||
enabled.setOnAction((e) -> {
|
enabled.setOnAction(e -> {
|
||||||
if(enabled.isSelected()) {
|
if(enabled.isSelected()) {
|
||||||
settings.disabledSites.remove(flirt4free.getName());
|
settings.disabledSites.remove(flirt4free.getName());
|
||||||
} else {
|
} else {
|
||||||
|
@ -45,7 +44,7 @@ public class Flirt4FreeConfigUI extends AbstractConfigUI {
|
||||||
layout.add(enabled, 1, row++);
|
layout.add(enabled, 1, row++);
|
||||||
|
|
||||||
layout.add(new Label("Flirt4Free User"), 0, 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) -> {
|
username.textProperty().addListener((ob, o, n) -> {
|
||||||
if(!n.equals(Config.getInstance().getSettings().flirt4freeUsername)) {
|
if(!n.equals(Config.getInstance().getSettings().flirt4freeUsername)) {
|
||||||
Config.getInstance().getSettings().flirt4freeUsername = username.getText();
|
Config.getInstance().getSettings().flirt4freeUsername = username.getText();
|
||||||
|
@ -59,7 +58,7 @@ public class Flirt4FreeConfigUI extends AbstractConfigUI {
|
||||||
layout.add(username, 1, row++);
|
layout.add(username, 1, row++);
|
||||||
|
|
||||||
layout.add(new Label("Flirt4Free Password"), 0, row);
|
layout.add(new Label("Flirt4Free Password"), 0, row);
|
||||||
PasswordField password = new PasswordField();
|
var password = new PasswordField();
|
||||||
password.setText(settings.flirt4freePassword);
|
password.setText(settings.flirt4freePassword);
|
||||||
password.textProperty().addListener((ob, o, n) -> {
|
password.textProperty().addListener((ob, o, n) -> {
|
||||||
if(!n.equals(Config.getInstance().getSettings().flirt4freePassword)) {
|
if(!n.equals(Config.getInstance().getSettings().flirt4freePassword)) {
|
||||||
|
@ -73,9 +72,9 @@ public class Flirt4FreeConfigUI extends AbstractConfigUI {
|
||||||
GridPane.setColumnSpan(password, 2);
|
GridPane.setColumnSpan(password, 2);
|
||||||
layout.add(password, 1, row++);
|
layout.add(password, 1, row++);
|
||||||
|
|
||||||
Button createAccount = new Button("Create new Account");
|
var createAccount = new Button("Create new Account");
|
||||||
createAccount.setOnAction((e) -> DesktopIntegration.open(flirt4free.getAffiliateLink()));
|
createAccount.setOnAction(e -> DesktopIntegration.open(flirt4free.getAffiliateLink()));
|
||||||
layout.add(createAccount, 1, row++);
|
layout.add(createAccount, 1, row);
|
||||||
GridPane.setColumnSpan(createAccount, 2);
|
GridPane.setColumnSpan(createAccount, 2);
|
||||||
GridPane.setMargin(username, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
|
GridPane.setMargin(username, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
|
||||||
GridPane.setMargin(password, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
|
GridPane.setMargin(password, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
|
||||||
|
|
|
@ -15,10 +15,8 @@ public class Flirt4FreeFavoritesTab extends ThumbOverviewTab implements Followed
|
||||||
|
|
||||||
public void setScene(Scene scene) {
|
public void setScene(Scene scene) {
|
||||||
scene.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
|
scene.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
|
||||||
if(this.isSelected()) {
|
if (this.isSelected() && event.getCode() == KeyCode.DELETE) {
|
||||||
if(event.getCode() == KeyCode.DELETE) {
|
follow(selectedThumbCells, false);
|
||||||
follow(selectedThumbCells, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,6 @@ import ctbrec.ui.SiteUiFactory;
|
||||||
import ctbrec.ui.tabs.PaginatedScheduledService;
|
import ctbrec.ui.tabs.PaginatedScheduledService;
|
||||||
import javafx.concurrent.Task;
|
import javafx.concurrent.Task;
|
||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
import okhttp3.Response;
|
|
||||||
|
|
||||||
public class Flirt4FreeFavoritesUpdateService extends PaginatedScheduledService {
|
public class Flirt4FreeFavoritesUpdateService extends PaginatedScheduledService {
|
||||||
private Flirt4Free flirt4free;
|
private Flirt4Free flirt4free;
|
||||||
|
@ -35,45 +34,49 @@ public class Flirt4FreeFavoritesUpdateService extends PaginatedScheduledService
|
||||||
return new Task<List<Model>>() {
|
return new Task<List<Model>>() {
|
||||||
@Override
|
@Override
|
||||||
public List<Model> call() throws IOException {
|
public List<Model> call() throws IOException {
|
||||||
List<Model> models = new ArrayList<>();
|
return loadModelList();
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ import javafx.scene.Scene;
|
||||||
import javafx.scene.control.Tab;
|
import javafx.scene.control.Tab;
|
||||||
import javafx.util.Duration;
|
import javafx.util.Duration;
|
||||||
|
|
||||||
public class Flirt4FreeTabProvider extends TabProvider {
|
public class Flirt4FreeTabProvider implements TabProvider {
|
||||||
|
|
||||||
private Flirt4Free flirt4Free;
|
private Flirt4Free flirt4Free;
|
||||||
private ThumbOverviewTab followedTab;
|
private ThumbOverviewTab followedTab;
|
||||||
|
@ -40,8 +40,8 @@ public class Flirt4FreeTabProvider extends TabProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
private ThumbOverviewTab createTab(String title, String url, Predicate<Flirt4FreeModel> filter) {
|
private ThumbOverviewTab createTab(String title, String url, Predicate<Flirt4FreeModel> filter) {
|
||||||
Flirt4FreeUpdateService s = new Flirt4FreeUpdateService(flirt4Free, url, filter);
|
var s = new Flirt4FreeUpdateService(flirt4Free, url, filter);
|
||||||
ThumbOverviewTab tab = new ThumbOverviewTab(title, s, flirt4Free);
|
var tab = new ThumbOverviewTab(title, s, flirt4Free);
|
||||||
tab.setRecorder(flirt4Free.getRecorder());
|
tab.setRecorder(flirt4Free.getRecorder());
|
||||||
s.setPeriod(Duration.seconds(60));
|
s.setPeriod(Duration.seconds(60));
|
||||||
return tab;
|
return tab;
|
||||||
|
|
|
@ -6,11 +6,9 @@ import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -45,11 +43,11 @@ public class Flirt4FreeUpdateService extends PaginatedScheduledService {
|
||||||
@Override
|
@Override
|
||||||
public List<Model> call() throws IOException {
|
public List<Model> call() throws IOException {
|
||||||
LOG.debug("Fetching page {}", url);
|
LOG.debug("Fetching page {}", url);
|
||||||
Request request = new Request.Builder()
|
var request = new Request.Builder()
|
||||||
.url(url)
|
.url(url)
|
||||||
.header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent)
|
.header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent)
|
||||||
.build();
|
.build();
|
||||||
try (Response response = flirt4Free.getHttpClient().execute(request)) {
|
try (var response = flirt4Free.getHttpClient().execute(request)) {
|
||||||
if (response.isSuccessful()) {
|
if (response.isSuccessful()) {
|
||||||
return parseResponse(response);
|
return parseResponse(response);
|
||||||
} else {
|
} else {
|
||||||
|
@ -62,26 +60,24 @@ public class Flirt4FreeUpdateService extends PaginatedScheduledService {
|
||||||
|
|
||||||
private List<Model> parseResponse(Response response) throws IOException {
|
private List<Model> parseResponse(Response response) throws IOException {
|
||||||
List<Flirt4FreeModel> models = new ArrayList<>();
|
List<Flirt4FreeModel> models = new ArrayList<>();
|
||||||
String body = response.body().string();
|
var body = response.body().string();
|
||||||
Matcher m = Pattern.compile("window\\.__homePageData__ = (\\{.*\\})", Pattern.DOTALL).matcher(body);
|
var m = Pattern.compile("window\\.__homePageData__ = (\\{.*\\})", Pattern.DOTALL).matcher(body);
|
||||||
if (m.find()) {
|
if (m.find()) {
|
||||||
JSONObject data = new JSONObject(m.group(1));
|
var data = new JSONObject(m.group(1));
|
||||||
JSONArray modelData = data.getJSONArray("models");
|
var modelData = data.getJSONArray("models");
|
||||||
LOG.debug("Found {} models", modelData.length());
|
LOG.debug("Found {} models", modelData.length());
|
||||||
for (int i = 0; i < modelData.length(); i++) {
|
for (var i = 0; i < modelData.length(); i++) {
|
||||||
JSONObject modelJson = modelData.getJSONObject(i);
|
var modelJson = modelData.getJSONObject(i);
|
||||||
try {
|
try {
|
||||||
Flirt4FreeModel model = parseModel(modelJson);
|
Flirt4FreeModel model = parseModel(modelJson);
|
||||||
if (model != null) {
|
models.add(model);
|
||||||
models.add(model);
|
|
||||||
}
|
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
LOG.warn("Couldn't parse model {}", modelJson);
|
LOG.warn("Couldn't parse model {}", modelJson);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return models.stream()
|
return models.stream()
|
||||||
.filter(filter)
|
.filter(filter)
|
||||||
.skip((page - 1) * MODELS_PER_PAGE)
|
.skip((page - 1) * (long)MODELS_PER_PAGE)
|
||||||
.limit(MODELS_PER_PAGE)
|
.limit(MODELS_PER_PAGE)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
} else {
|
} else {
|
||||||
|
@ -90,14 +86,14 @@ public class Flirt4FreeUpdateService extends PaginatedScheduledService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Flirt4FreeModel parseModel(JSONObject modelData) {
|
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);
|
Flirt4FreeModel model = (Flirt4FreeModel) flirt4Free.createModel(name);
|
||||||
model.setDisplayName(modelData.getString("display"));
|
model.setDisplayName(modelData.getString("display"));
|
||||||
model.setDescription(modelData.getString("topic"));
|
model.setDescription(modelData.getString("topic"));
|
||||||
model.setUrl(Flirt4Free.BASE_URI + "/rooms/" + model.getName() + '/');
|
model.setUrl(Flirt4Free.BASE_URI + "/rooms/" + model.getName() + '/');
|
||||||
model.setNew(modelData.optString("is_new", "0").equals("1"));
|
model.setNew(modelData.optString("is_new", "0").equals("1"));
|
||||||
String videoHost = modelData.getString("video_host");
|
var videoHost = modelData.getString("video_host");
|
||||||
String modelId = modelData.getString("model_id");
|
var modelId = modelData.getString("model_id");
|
||||||
model.setId(modelId);
|
model.setId(modelId);
|
||||||
String streamUrl = "https://manifest.vscdns.com/manifest.m3u8.m3u8?key=nil&provider=level3&secure=true&host=" + videoHost
|
String streamUrl = "https://manifest.vscdns.com/manifest.m3u8.m3u8?key=nil&provider=level3&secure=true&host=" + videoHost
|
||||||
+ "&model_id=" + modelId;
|
+ "&model_id=" + modelId;
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package ctbrec.ui.sites.jasmin;
|
package ctbrec.ui.sites.jasmin;
|
||||||
|
|
||||||
import ctbrec.Config;
|
import ctbrec.Config;
|
||||||
import ctbrec.Settings;
|
|
||||||
import ctbrec.sites.jasmin.LiveJasmin;
|
import ctbrec.sites.jasmin.LiveJasmin;
|
||||||
import ctbrec.ui.DesktopIntegration;
|
import ctbrec.ui.DesktopIntegration;
|
||||||
import ctbrec.ui.settings.SettingsTab;
|
import ctbrec.ui.settings.SettingsTab;
|
||||||
|
@ -25,15 +24,15 @@ public class LiveJasminConfigUi extends AbstractConfigUI {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Parent createConfigPanel() {
|
public Parent createConfigPanel() {
|
||||||
Settings settings = Config.getInstance().getSettings();
|
var settings = Config.getInstance().getSettings();
|
||||||
GridPane layout = SettingsTab.createGridLayout();
|
var layout = SettingsTab.createGridLayout();
|
||||||
|
|
||||||
int row = 0;
|
var row = 0;
|
||||||
Label l = new Label("Active");
|
var l = new Label("Active");
|
||||||
layout.add(l, 0, row);
|
layout.add(l, 0, row);
|
||||||
CheckBox enabled = new CheckBox();
|
var enabled = new CheckBox();
|
||||||
enabled.setSelected(!settings.disabledSites.contains(liveJasmin.getName()));
|
enabled.setSelected(!settings.disabledSites.contains(liveJasmin.getName()));
|
||||||
enabled.setOnAction((e) -> {
|
enabled.setOnAction(e -> {
|
||||||
if(enabled.isSelected()) {
|
if(enabled.isSelected()) {
|
||||||
settings.disabledSites.remove(liveJasmin.getName());
|
settings.disabledSites.remove(liveJasmin.getName());
|
||||||
} else {
|
} else {
|
||||||
|
@ -45,7 +44,7 @@ public class LiveJasminConfigUi extends AbstractConfigUI {
|
||||||
layout.add(enabled, 1, row++);
|
layout.add(enabled, 1, row++);
|
||||||
|
|
||||||
layout.add(new Label("LiveJasmin User"), 0, 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) -> {
|
username.textProperty().addListener((ob, o, n) -> {
|
||||||
if(!n.equals(Config.getInstance().getSettings().livejasminUsername)) {
|
if(!n.equals(Config.getInstance().getSettings().livejasminUsername)) {
|
||||||
Config.getInstance().getSettings().livejasminUsername = n;
|
Config.getInstance().getSettings().livejasminUsername = n;
|
||||||
|
@ -59,7 +58,7 @@ public class LiveJasminConfigUi extends AbstractConfigUI {
|
||||||
layout.add(username, 1, row++);
|
layout.add(username, 1, row++);
|
||||||
|
|
||||||
layout.add(new Label("LiveJasmin Password"), 0, row);
|
layout.add(new Label("LiveJasmin Password"), 0, row);
|
||||||
PasswordField password = new PasswordField();
|
var password = new PasswordField();
|
||||||
password.setText(Config.getInstance().getSettings().livejasminPassword);
|
password.setText(Config.getInstance().getSettings().livejasminPassword);
|
||||||
password.textProperty().addListener((ob, o, n) -> {
|
password.textProperty().addListener((ob, o, n) -> {
|
||||||
if(!n.equals(Config.getInstance().getSettings().livejasminPassword)) {
|
if(!n.equals(Config.getInstance().getSettings().livejasminPassword)) {
|
||||||
|
@ -74,7 +73,7 @@ public class LiveJasminConfigUi extends AbstractConfigUI {
|
||||||
layout.add(password, 1, row++);
|
layout.add(password, 1, row++);
|
||||||
|
|
||||||
layout.add(new Label("LiveJasmin Base URL"), 0, 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.setText(Config.getInstance().getSettings().livejasminBaseUrl);
|
||||||
baseUrl.textProperty().addListener((ob, o, n) -> {
|
baseUrl.textProperty().addListener((ob, o, n) -> {
|
||||||
Config.getInstance().getSettings().livejasminBaseUrl = baseUrl.getText();
|
Config.getInstance().getSettings().livejasminBaseUrl = baseUrl.getText();
|
||||||
|
@ -85,9 +84,9 @@ public class LiveJasminConfigUi extends AbstractConfigUI {
|
||||||
GridPane.setColumnSpan(baseUrl, 2);
|
GridPane.setColumnSpan(baseUrl, 2);
|
||||||
layout.add(baseUrl, 1, row++);
|
layout.add(baseUrl, 1, row++);
|
||||||
|
|
||||||
Button createAccount = new Button("Create new Account");
|
var createAccount = new Button("Create new Account");
|
||||||
createAccount.setOnAction((e) -> DesktopIntegration.open(liveJasmin.getAffiliateLink()));
|
createAccount.setOnAction(e -> DesktopIntegration.open(liveJasmin.getAffiliateLink()));
|
||||||
layout.add(createAccount, 1, row++);
|
layout.add(createAccount, 1, row);
|
||||||
GridPane.setColumnSpan(createAccount, 2);
|
GridPane.setColumnSpan(createAccount, 2);
|
||||||
GridPane.setMargin(username, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
|
GridPane.setMargin(username, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
|
||||||
GridPane.setMargin(password, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
|
GridPane.setMargin(password, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
|
||||||
|
|
|
@ -4,7 +4,6 @@ import java.io.IOException;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -19,23 +18,24 @@ import okhttp3.HttpUrl;
|
||||||
|
|
||||||
public class LiveJasminElectronLoginDialog {
|
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";
|
public static final String URL = LiveJasmin.baseUrl + "/en/auth/login";
|
||||||
private CookieJar cookieJar;
|
private CookieJar cookieJar;
|
||||||
private ExternalBrowser browser;
|
private ExternalBrowser browser;
|
||||||
|
|
||||||
public LiveJasminElectronLoginDialog(CookieJar cookieJar) throws Exception {
|
public LiveJasminElectronLoginDialog(CookieJar cookieJar) throws IOException {
|
||||||
this.cookieJar = cookieJar;
|
this.cookieJar = cookieJar;
|
||||||
browser = ExternalBrowser.getInstance();
|
browser = ExternalBrowser.getInstance();
|
||||||
try {
|
try {
|
||||||
JSONObject config = new JSONObject();
|
var config = new JSONObject();
|
||||||
config.put("url", URL);
|
config.put("url", URL);
|
||||||
config.put("w", 640);
|
config.put("w", 640);
|
||||||
config.put("h", 720);
|
config.put("h", 720);
|
||||||
JSONObject msg = new JSONObject();
|
var msg = new JSONObject();
|
||||||
msg.put("config", config);
|
msg.put("config", config);
|
||||||
browser.run(msg, msgHandler);
|
browser.run(msg, msgHandler);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
throw new IOException("Couldn't wait for login dialog", e);
|
throw new IOException("Couldn't wait for login dialog", e);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LOG.debug("Error while starting the browser or communication to it", 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) -> {
|
private Consumer<String> msgHandler = line -> {
|
||||||
//LOG.debug("Browser: {}", line);
|
|
||||||
if(!line.startsWith("{")) {
|
if(!line.startsWith("{")) {
|
||||||
System.err.println(line);
|
System.err.println(line); // NOSONAR
|
||||||
} else {
|
} else {
|
||||||
JSONObject json = new JSONObject(line);
|
var json = new JSONObject(line);
|
||||||
if(json.has("url")) {
|
if(json.has("url")) {
|
||||||
String url = json.getString("url");
|
var url = json.getString("url");
|
||||||
if(url.endsWith("/auth/login")) {
|
if(url.endsWith("/auth/login")) {
|
||||||
try {
|
try {
|
||||||
String username = Config.getInstance().getSettings().livejasminUsername;
|
String username = Config.getInstance().getSettings().livejasminUsername;
|
||||||
|
@ -73,9 +72,9 @@ public class LiveJasminElectronLoginDialog {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(json.has("cookies")) {
|
if(json.has("cookies")) {
|
||||||
JSONArray _cookies = json.getJSONArray("cookies");
|
var cookiesFromBrowser = json.getJSONArray("cookies");
|
||||||
for (int i = 0; i < _cookies.length(); i++) {
|
for (var i = 0; i < cookiesFromBrowser.length(); i++) {
|
||||||
JSONObject cookie = _cookies.getJSONObject(i);
|
var cookie = cookiesFromBrowser.getJSONObject(i);
|
||||||
Builder b = new Cookie.Builder()
|
Builder b = new Cookie.Builder()
|
||||||
.path("/")
|
.path("/")
|
||||||
.domain(LiveJasmin.baseDomain)
|
.domain(LiveJasmin.baseDomain)
|
||||||
|
|
|
@ -15,10 +15,8 @@ public class LiveJasminFollowedTab extends LiveJasminTab implements FollowedTab
|
||||||
@Override
|
@Override
|
||||||
public void setScene(Scene scene) {
|
public void setScene(Scene scene) {
|
||||||
scene.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
|
scene.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
|
||||||
if(this.isSelected()) {
|
if (this.isSelected() && event.getCode() == KeyCode.DELETE) {
|
||||||
if(event.getCode() == KeyCode.DELETE) {
|
follow(selectedThumbCells, false);
|
||||||
follow(selectedThumbCells, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,6 @@ import ctbrec.ui.SiteUiFactory;
|
||||||
import ctbrec.ui.tabs.PaginatedScheduledService;
|
import ctbrec.ui.tabs.PaginatedScheduledService;
|
||||||
import javafx.concurrent.Task;
|
import javafx.concurrent.Task;
|
||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
import okhttp3.Response;
|
|
||||||
|
|
||||||
public class LiveJasminFollowedUpdateService extends PaginatedScheduledService {
|
public class LiveJasminFollowedUpdateService extends PaginatedScheduledService {
|
||||||
|
|
||||||
|
@ -50,16 +49,16 @@ public class LiveJasminFollowedUpdateService extends PaginatedScheduledService {
|
||||||
throw new NotLoggedInExcetion("Couldn't login to livejasmin");
|
throw new NotLoggedInExcetion("Couldn't login to livejasmin");
|
||||||
}
|
}
|
||||||
LOG.debug("Fetching page {}", url);
|
LOG.debug("Fetching page {}", url);
|
||||||
Request request = new Request.Builder()
|
var request = new Request.Builder()
|
||||||
.url(url)
|
.url(url)
|
||||||
.header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent)
|
.header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent)
|
||||||
.header(ACCEPT, "*/*")
|
.header(ACCEPT, "*/*")
|
||||||
.header(ACCEPT_LANGUAGE, Locale.ENGLISH.getLanguage())
|
.header(ACCEPT_LANGUAGE, Locale.ENGLISH.getLanguage())
|
||||||
.header(REFERER, liveJasmin.getBaseUrl())
|
.header(REFERER, liveJasmin.getBaseUrl())
|
||||||
.build();
|
.build();
|
||||||
try (Response response = liveJasmin.getHttpClient().execute(request)) {
|
try (var response = liveJasmin.getHttpClient().execute(request)) {
|
||||||
if (response.isSuccessful()) {
|
if (response.isSuccessful()) {
|
||||||
String body = response.body().string();
|
var body = response.body().string();
|
||||||
List<Model> models = new ArrayList<>();
|
List<Model> models = new ArrayList<>();
|
||||||
Elements modelCells = getTags(body, "article[class~=perf_container]");
|
Elements modelCells = getTags(body, "article[class~=perf_container]");
|
||||||
for (Element modelCell : modelCells) {
|
for (Element modelCell : modelCells) {
|
||||||
|
|
|
@ -41,7 +41,7 @@ public class LiveJasminSiteUi extends AbstractSiteUi {
|
||||||
public synchronized boolean login() throws IOException {
|
public synchronized boolean login() throws IOException {
|
||||||
// renew login every 30 min
|
// renew login every 30 min
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
boolean renew = false;
|
var renew = false;
|
||||||
if ((now - lastLoginTime) > TimeUnit.MINUTES.toMillis(30)) {
|
if ((now - lastLoginTime) > TimeUnit.MINUTES.toMillis(30)) {
|
||||||
renew = true;
|
renew = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,9 @@ package ctbrec.ui.sites.jasmin;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import ctbrec.Config;
|
import ctbrec.Config;
|
||||||
import ctbrec.sites.Site;
|
import ctbrec.sites.Site;
|
||||||
import ctbrec.ui.tabs.PaginatedScheduledService;
|
import ctbrec.ui.tabs.PaginatedScheduledService;
|
||||||
|
@ -14,6 +17,7 @@ import javafx.scene.input.KeyCode;
|
||||||
import javafx.scene.input.KeyEvent;
|
import javafx.scene.input.KeyEvent;
|
||||||
|
|
||||||
public class LiveJasminTab extends ThumbOverviewTab {
|
public class LiveJasminTab extends ThumbOverviewTab {
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(LiveJasminTab.class);
|
||||||
protected Label status;
|
protected Label status;
|
||||||
protected Button acknowledge = new Button("That's alright");
|
protected Button acknowledge = new Button("That's alright");
|
||||||
private boolean betaAcknowledged = Config.getInstance().getSettings().livejasminBetaAcknowledged;
|
private boolean betaAcknowledged = Config.getInstance().getSettings().livejasminBetaAcknowledged;
|
||||||
|
@ -36,6 +40,7 @@ public class LiveJasminTab extends ThumbOverviewTab {
|
||||||
try {
|
try {
|
||||||
Config.getInstance().save();
|
Config.getInstance().save();
|
||||||
} catch (IOException e1) {
|
} catch (IOException e1) {
|
||||||
|
LOG.error("Couldn't save config", e1);
|
||||||
}
|
}
|
||||||
status.setText("Loading...");
|
status.setText("Loading...");
|
||||||
grid.getChildren().remove(acknowledge);
|
grid.getChildren().remove(acknowledge);
|
||||||
|
@ -47,11 +52,6 @@ public class LiveJasminTab extends ThumbOverviewTab {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void createGui() {
|
|
||||||
super.createGui();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onSuccess() {
|
protected void onSuccess() {
|
||||||
if(Config.getInstance().getSettings().livejasminBetaAcknowledged) {
|
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) {
|
public void setScene(Scene scene) {
|
||||||
scene.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
|
scene.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
|
||||||
if(this.isSelected()) {
|
if (this.isSelected() && event.getCode() == KeyCode.DELETE) {
|
||||||
if(event.getCode() == KeyCode.DELETE) {
|
follow(selectedThumbCells, false);
|
||||||
follow(selectedThumbCells, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import javafx.scene.Scene;
|
||||||
import javafx.scene.control.Tab;
|
import javafx.scene.control.Tab;
|
||||||
import javafx.util.Duration;
|
import javafx.util.Duration;
|
||||||
|
|
||||||
public class LiveJasminTabProvider extends TabProvider {
|
public class LiveJasminTabProvider implements TabProvider {
|
||||||
|
|
||||||
private LiveJasmin liveJasmin;
|
private LiveJasmin liveJasmin;
|
||||||
private LiveJasminFollowedTab followedTab;
|
private LiveJasminFollowedTab followedTab;
|
||||||
|
@ -43,7 +43,7 @@ public class LiveJasminTabProvider extends TabProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
private ThumbOverviewTab createTab(String title, String url) {
|
private ThumbOverviewTab createTab(String title, String url) {
|
||||||
LiveJasminUpdateService s = new LiveJasminUpdateService(liveJasmin, url);
|
var s = new LiveJasminUpdateService(liveJasmin, url);
|
||||||
s.setPeriod(Duration.seconds(60));
|
s.setPeriod(Duration.seconds(60));
|
||||||
ThumbOverviewTab tab = new LiveJasminTab(title, s, liveJasmin);
|
ThumbOverviewTab tab = new LiveJasminTab(title, s, liveJasmin);
|
||||||
tab.setRecorder(liveJasmin.getRecorder());
|
tab.setRecorder(liveJasmin.getRecorder());
|
||||||
|
|
|
@ -8,25 +8,21 @@ import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import ctbrec.Config;
|
import ctbrec.Config;
|
||||||
import ctbrec.Model;
|
import ctbrec.Model;
|
||||||
import ctbrec.io.CookieJarImpl;
|
|
||||||
import ctbrec.io.HttpException;
|
import ctbrec.io.HttpException;
|
||||||
import ctbrec.sites.jasmin.LiveJasmin;
|
import ctbrec.sites.jasmin.LiveJasmin;
|
||||||
import ctbrec.sites.jasmin.LiveJasminModel;
|
import ctbrec.sites.jasmin.LiveJasminModel;
|
||||||
import ctbrec.ui.SiteUI;
|
|
||||||
import ctbrec.ui.SiteUiFactory;
|
import ctbrec.ui.SiteUiFactory;
|
||||||
import ctbrec.ui.tabs.PaginatedScheduledService;
|
import ctbrec.ui.tabs.PaginatedScheduledService;
|
||||||
import javafx.concurrent.Task;
|
import javafx.concurrent.Task;
|
||||||
import okhttp3.Cookie;
|
import okhttp3.Cookie;
|
||||||
import okhttp3.HttpUrl;
|
import okhttp3.HttpUrl;
|
||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
import okhttp3.Response;
|
|
||||||
|
|
||||||
public class LiveJasminUpdateService extends PaginatedScheduledService {
|
public class LiveJasminUpdateService extends PaginatedScheduledService {
|
||||||
|
|
||||||
|
@ -45,8 +41,8 @@ public class LiveJasminUpdateService extends PaginatedScheduledService {
|
||||||
@Override
|
@Override
|
||||||
public List<Model> call() throws IOException {
|
public List<Model> call() throws IOException {
|
||||||
// sort by popularity
|
// sort by popularity
|
||||||
CookieJarImpl cookieJar = liveJasmin.getHttpClient().getCookieJar();
|
var cookieJar = liveJasmin.getHttpClient().getCookieJar();
|
||||||
Cookie sortCookie = new Cookie.Builder()
|
var sortCookie = new Cookie.Builder()
|
||||||
.domain(LiveJasmin.baseDomain)
|
.domain(LiveJasmin.baseDomain)
|
||||||
.name("listPageOrderType")
|
.name("listPageOrderType")
|
||||||
.value("most_popular")
|
.value("most_popular")
|
||||||
|
@ -55,7 +51,7 @@ public class LiveJasminUpdateService extends PaginatedScheduledService {
|
||||||
|
|
||||||
// TODO find out how to switch pages
|
// TODO find out how to switch pages
|
||||||
LOG.debug("Fetching page {}", url);
|
LOG.debug("Fetching page {}", url);
|
||||||
Request request = new Request.Builder()
|
var request = new Request.Builder()
|
||||||
.url(url)
|
.url(url)
|
||||||
.addHeader(USER_AGENT, Config.getInstance().getSettings().httpUserAgent)
|
.addHeader(USER_AGENT, Config.getInstance().getSettings().httpUserAgent)
|
||||||
.addHeader(ACCEPT, MIMETYPE_APPLICATION_JSON)
|
.addHeader(ACCEPT, MIMETYPE_APPLICATION_JSON)
|
||||||
|
@ -63,31 +59,16 @@ public class LiveJasminUpdateService extends PaginatedScheduledService {
|
||||||
.addHeader(REFERER, liveJasmin.getBaseUrl())
|
.addHeader(REFERER, liveJasmin.getBaseUrl())
|
||||||
.addHeader(X_REQUESTED_WITH, XML_HTTP_REQUEST)
|
.addHeader(X_REQUESTED_WITH, XML_HTTP_REQUEST)
|
||||||
.build();
|
.build();
|
||||||
try (Response response = liveJasmin.getHttpClient().execute(request)) {
|
try (var response = liveJasmin.getHttpClient().execute(request)) {
|
||||||
LOG.debug("Response {} {}", response.code(), response.message());
|
LOG.debug("Response {} {}", response.code(), response.message());
|
||||||
if (response.isSuccessful()) {
|
if (response.isSuccessful()) {
|
||||||
String body = response.body().string();
|
var body = response.body().string();
|
||||||
List<Model> models = new ArrayList<>();
|
List<Model> models = new ArrayList<>();
|
||||||
JSONObject json = new JSONObject(body);
|
var json = new JSONObject(body);
|
||||||
//LOG.debug(json.toString(2));
|
|
||||||
if(json.optBoolean("success")) {
|
if(json.optBoolean("success")) {
|
||||||
JSONObject data = json.getJSONObject("data");
|
parseModels(models, json);
|
||||||
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);
|
|
||||||
}
|
|
||||||
} else if(json.optString("error").equals("Please login.")) {
|
} else if(json.optString("error").equals("Please login.")) {
|
||||||
SiteUI siteUI = SiteUiFactory.getUi(liveJasmin);
|
var siteUI = SiteUiFactory.getUi(liveJasmin);
|
||||||
if(siteUI.login()) {
|
if(siteUI.login()) {
|
||||||
return call();
|
return call();
|
||||||
} else {
|
} 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package ctbrec.ui.sites.manyvids;
|
package ctbrec.ui.sites.manyvids;
|
||||||
|
|
||||||
import ctbrec.Config;
|
import ctbrec.Config;
|
||||||
import ctbrec.Settings;
|
|
||||||
import ctbrec.sites.manyvids.MVLive;
|
import ctbrec.sites.manyvids.MVLive;
|
||||||
import ctbrec.ui.settings.SettingsTab;
|
import ctbrec.ui.settings.SettingsTab;
|
||||||
import ctbrec.ui.sites.AbstractConfigUI;
|
import ctbrec.ui.sites.AbstractConfigUI;
|
||||||
|
@ -20,15 +19,15 @@ public class MVLiveConfigUi extends AbstractConfigUI {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Parent createConfigPanel() {
|
public Parent createConfigPanel() {
|
||||||
Settings settings = Config.getInstance().getSettings();
|
var settings = Config.getInstance().getSettings();
|
||||||
GridPane layout = SettingsTab.createGridLayout();
|
GridPane layout = SettingsTab.createGridLayout();
|
||||||
|
|
||||||
int row = 0;
|
var row = 0;
|
||||||
Label l = new Label("Active");
|
var l = new Label("Active");
|
||||||
layout.add(l, 0, row);
|
layout.add(l, 0, row);
|
||||||
CheckBox enabled = new CheckBox();
|
var enabled = new CheckBox();
|
||||||
enabled.setSelected(!settings.disabledSites.contains(site.getName()));
|
enabled.setSelected(!settings.disabledSites.contains(site.getName()));
|
||||||
enabled.setOnAction((e) -> {
|
enabled.setOnAction(e -> {
|
||||||
if(enabled.isSelected()) {
|
if(enabled.isSelected()) {
|
||||||
settings.disabledSites.remove(site.getName());
|
settings.disabledSites.remove(site.getName());
|
||||||
} else {
|
} else {
|
||||||
|
@ -37,7 +36,7 @@ public class MVLiveConfigUi extends AbstractConfigUI {
|
||||||
save();
|
save();
|
||||||
});
|
});
|
||||||
GridPane.setMargin(enabled, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
|
GridPane.setMargin(enabled, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
|
||||||
layout.add(enabled, 1, row++);
|
layout.add(enabled, 1, row);
|
||||||
return layout;
|
return layout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ import ctbrec.ui.tabs.ThumbOverviewTab;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
import javafx.scene.control.Tab;
|
import javafx.scene.control.Tab;
|
||||||
|
|
||||||
public class MVLiveTabProvider extends TabProvider {
|
public class MVLiveTabProvider implements TabProvider {
|
||||||
|
|
||||||
private MVLive mvlive;
|
private MVLive mvlive;
|
||||||
|
|
||||||
|
@ -26,8 +26,8 @@ public class MVLiveTabProvider extends TabProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Tab createTab(String title) {
|
private Tab createTab(String title) {
|
||||||
MVLiveUpdateService updateService = new MVLiveUpdateService(mvlive);
|
var updateService = new MVLiveUpdateService(mvlive);
|
||||||
ThumbOverviewTab tab = new ThumbOverviewTab(title, updateService, mvlive);
|
var tab = new ThumbOverviewTab(title, updateService, mvlive);
|
||||||
tab.setRecorder(mvlive.getRecorder());
|
tab.setRecorder(mvlive.getRecorder());
|
||||||
tab.setImageAspectRatio(1);
|
tab.setImageAspectRatio(1);
|
||||||
return tab;
|
return tab;
|
||||||
|
|
|
@ -57,50 +57,59 @@ public class FriendsUpdateService extends PaginatedScheduledService {
|
||||||
.build();
|
.build();
|
||||||
try (Response resp = myFreeCams.getHttpClient().execute(req)) {
|
try (Response resp = myFreeCams.getHttpClient().execute(req)) {
|
||||||
if (resp.isSuccessful()) {
|
if (resp.isSuccessful()) {
|
||||||
String body = resp.body().string().substring(4);
|
var body = resp.body().string().substring(4);
|
||||||
try {
|
parseModels(body, models);
|
||||||
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);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
LOG.error("Couldn't load friends list {} {}", resp.code(), resp.message());
|
LOG.error("Couldn't load friends list {} {}", resp.code(), resp.message());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
boolean filterOnline = mode == Mode.ONLINE;
|
boolean filterOnline = mode == Mode.ONLINE;
|
||||||
return models.stream().filter(m -> {
|
return models.stream()
|
||||||
try {
|
.filter(m -> {
|
||||||
return m.isOnline() == filterOnline;
|
try {
|
||||||
} catch (Exception e) {
|
return m.isOnline() == filterOnline;
|
||||||
return false;
|
} catch (InterruptedException e) {
|
||||||
}
|
Thread.currentThread().interrupt();
|
||||||
})
|
return false;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
})
|
||||||
.sorted((m1, m2) -> (int) (m2.getCamScore() - m1.getCamScore()))
|
.sorted((m1, m2) -> (int) (m2.getCamScore() - m1.getCamScore()))
|
||||||
.skip((page - 1) * 50l)
|
.skip((page - 1) * 50l)
|
||||||
.limit(50)
|
.limit(50)
|
||||||
.collect(Collectors.toList());
|
.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) {
|
public void setMode(Mode mode) {
|
||||||
this.mode = mode;
|
this.mode = mode;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,8 +20,8 @@ public class HDCamsUpdateService extends PaginatedScheduledService {
|
||||||
return new Task<List<Model>>() {
|
return new Task<List<Model>>() {
|
||||||
@Override
|
@Override
|
||||||
public List<Model> call() throws IOException {
|
public List<Model> call() throws IOException {
|
||||||
MyFreeCamsClient client = MyFreeCamsClient.getInstance();
|
var client = MyFreeCamsClient.getInstance();
|
||||||
int modelsPerPage = 50;
|
var modelsPerPage = 50;
|
||||||
|
|
||||||
return client.getModels().stream()
|
return client.getModels().stream()
|
||||||
.filter(m -> m.getPreview() != null)
|
.filter(m -> m.getPreview() != null)
|
||||||
|
@ -33,7 +33,10 @@ public class HDCamsUpdateService extends PaginatedScheduledService {
|
||||||
.filter(m -> {
|
.filter(m -> {
|
||||||
try {
|
try {
|
||||||
return m.isOnline();
|
return m.isOnline();
|
||||||
} catch(Exception e) {
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
return false;
|
||||||
|
} catch (Exception e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue