diff --git a/client/.gitignore b/client/.gitignore
index 2c4e8e27..222879c9 100644
--- a/client/.gitignore
+++ b/client/.gitignore
@@ -6,3 +6,4 @@
/ctbrec-tunnel.sh
/jre/
/server-local.sh
+/browser/
diff --git a/client/pom.xml b/client/pom.xml
index 435967b8..c21fedba 100644
--- a/client/pom.xml
+++ b/client/pom.xml
@@ -4,7 +4,7 @@
4.0.0
client
-
+
ctbrec
master
@@ -80,7 +80,7 @@
org.openjfx
- javafx-web
+ javafx-media
diff --git a/client/src/assembly/linux-jre.xml b/client/src/assembly/linux-jre.xml
index 4cf3b8ba..182be496 100644
--- a/client/src/assembly/linux-jre.xml
+++ b/client/src/assembly/linux-jre.xml
@@ -38,5 +38,13 @@
ctbrec/jre
false
+
+ browser/ctbrec-minimal-browser-linux-x64
+
+ **/*
+
+ ctbrec/browser
+ false
+
diff --git a/client/src/assembly/linux.xml b/client/src/assembly/linux.xml
index 96e803e9..a692495d 100644
--- a/client/src/assembly/linux.xml
+++ b/client/src/assembly/linux.xml
@@ -29,4 +29,14 @@
ctbrec
+
+
+ browser/ctbrec-minimal-browser-linux-x64
+
+ **/*
+
+ ctbrec/browser
+ false
+
+
diff --git a/client/src/assembly/macos-jre.xml b/client/src/assembly/macos-jre.xml
index ec549040..31f2ff40 100644
--- a/client/src/assembly/macos-jre.xml
+++ b/client/src/assembly/macos-jre.xml
@@ -38,5 +38,13 @@
ctbrec/jre
false
+
+ browser/ctbrec-minimal-browser-darwin-x64
+
+ **/*
+
+ ctbrec/browser
+ false
+
diff --git a/client/src/assembly/macos.xml b/client/src/assembly/macos.xml
index fb7620ab..f9c9fcca 100644
--- a/client/src/assembly/macos.xml
+++ b/client/src/assembly/macos.xml
@@ -29,4 +29,14 @@
ctbrec
+
+
+ browser/ctbrec-minimal-browser-darwin-x64
+
+ **/*
+
+ ctbrec/browser
+ false
+
+
diff --git a/client/src/assembly/win64-jre.xml b/client/src/assembly/win64-jre.xml
index f994af4c..06a6cb8d 100644
--- a/client/src/assembly/win64-jre.xml
+++ b/client/src/assembly/win64-jre.xml
@@ -40,5 +40,13 @@
ctbrec/jre
false
+
+ browser/ctbrec-minimal-browser-win32-x64
+
+ **/*
+
+ ctbrec/browser
+ false
+
diff --git a/client/src/assembly/win64.xml b/client/src/assembly/win64.xml
index fd31b626..1f1cf1e7 100644
--- a/client/src/assembly/win64.xml
+++ b/client/src/assembly/win64.xml
@@ -31,4 +31,14 @@
ctbrec
+
+
+ browser/ctbrec-minimal-browser-win32-x64
+
+ **/*
+
+ ctbrec/browser
+ false
+
+
diff --git a/client/src/main/java/ctbrec/ui/CamrecApplication.java b/client/src/main/java/ctbrec/ui/CamrecApplication.java
index 29ff5a0c..0e8cf692 100644
--- a/client/src/main/java/ctbrec/ui/CamrecApplication.java
+++ b/client/src/main/java/ctbrec/ui/CamrecApplication.java
@@ -196,6 +196,10 @@ public class CamrecApplication extends Application {
System.exit(1);
});
}
+ try {
+ ExternalBrowser.getInstance().close();
+ } catch (IOException e) {
+ }
}
}.start();
});
diff --git a/client/src/main/java/ctbrec/ui/DonateTabHtml.java b/client/src/main/java/ctbrec/ui/DonateTabHtml.java
deleted file mode 100644
index de1fc23e..00000000
--- a/client/src/main/java/ctbrec/ui/DonateTabHtml.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package ctbrec.ui;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javafx.scene.control.Tab;
-import javafx.scene.web.WebEngine;
-import javafx.scene.web.WebView;
-
-public class DonateTabHtml extends Tab {
-
- private static final transient Logger LOG = LoggerFactory.getLogger(DonateTabHtml.class);
-
- private WebView browser;
-
- public DonateTabHtml() {
- setClosable(false);
- setText("Donate");
-
- browser = new WebView();
- try {
- WebEngine webEngine = browser.getEngine();
- webEngine.load("https://0xboobface.github.io/ctbrec/#donate");
- webEngine.setJavaScriptEnabled(true);
- webEngine.setOnAlert((e) -> {
- System.out.println(e.getData());
- });
- setContent(browser);
- } catch (Exception e) {
- LOG.error("Couldn't load donate.html", e);
- }
- }
-}
diff --git a/client/src/main/java/ctbrec/ui/ExternalBrowser.java b/client/src/main/java/ctbrec/ui/ExternalBrowser.java
new file mode 100644
index 00000000..648014d7
--- /dev/null
+++ b/client/src/main/java/ctbrec/ui/ExternalBrowser.java
@@ -0,0 +1,141 @@
+package ctbrec.ui;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.function.Consumer;
+
+import org.json.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import ctbrec.OS;
+import ctbrec.io.StreamRedirectThread;
+
+public class ExternalBrowser implements AutoCloseable {
+ private static final transient Logger LOG = LoggerFactory.getLogger(ExternalBrowser.class);
+ private static final ExternalBrowser INSTANCE = new ExternalBrowser();
+ private Lock lock = new ReentrantLock();
+
+ private Process p;
+ private Consumer messageListener;
+ private InputStream in;
+ private OutputStream out;
+ private Socket socket;
+ private Thread reader;
+ private volatile boolean stopped = true;
+
+ public static ExternalBrowser getInstance() {
+ return INSTANCE;
+ }
+
+ public void run(String jsonConfig, Consumer messageListener) throws InterruptedException, IOException {
+ lock.lock();
+ stopped = false;
+ this.messageListener = messageListener;
+
+ p = new ProcessBuilder(OS.getBrowserCommand()).start();
+ new StreamRedirectThread(p.getInputStream(), System.err);
+ new StreamRedirectThread(p.getErrorStream(), System.err);
+ LOG.debug("Browser started");
+
+ connectToRemoteControlSocket();
+ LOG.debug("Connected to remote control server. Sending config {}", jsonConfig);
+
+ out.write(jsonConfig.getBytes("utf-8"));
+ out.write('\n');
+ out.flush();
+
+ LOG.debug("Waiting for browser to terminate");
+ p.waitFor();
+ int exitValue = p.exitValue();
+ p = null;
+ LOG.debug("Browser Process terminated with {}", exitValue);
+ }
+
+ private void connectToRemoteControlSocket() {
+ for (int i = 0; i < 20; i++) {
+ try {
+ socket = new Socket("localhost", 3202);
+ in = socket.getInputStream();
+ out = socket.getOutputStream();
+ reader = new Thread(this::readBrowserOutput);
+ reader.start();
+ return;
+ } catch (IOException e) {
+ if(i == 19) {
+ LOG.error("Connection to remote control socket failed", e);
+ return;
+ }
+ }
+
+ // wait a bit, so that the remote server socket can be opened by electron
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+
+ public void executeJavaScript(String javaScript) throws IOException {
+ //LOG.debug("Executing JS {}", javaScript);
+ JSONObject script = new JSONObject();
+ script.put("execute", javaScript);
+ out.write(script.toString().getBytes("utf-8"));
+ out.write('\n');
+ out.flush();
+ if(javaScript.equals("quit")) {
+ stopped = true;
+ }
+ }
+
+ @Override
+ public void close() throws IOException {
+ if(stopped) {
+ return;
+ }
+ stopped = true;
+ executeJavaScript("quit");
+ if(socket != null) {
+ socket.close();
+ socket = null;
+ }
+ messageListener = null;
+ reader = null;
+ in = null;
+ out = null;
+ if(p != null) {
+ p.destroy();
+ }
+ }
+
+ private void readBrowserOutput() {
+ LOG.debug("Browser output reader started");
+ try {
+ BufferedReader br = new BufferedReader(new InputStreamReader(in));
+ String line;
+ while( !Thread.interrupted() && (line = br.readLine()) != null ) {
+ if(!line.startsWith("{")) {
+ System.err.println(line);
+ } else {
+ if(messageListener != null) {
+ messageListener.accept(line);
+ }
+ }
+ }
+ } catch (IOException e) {
+ if(!stopped) {
+ LOG.error("Couldn't read browser output", e);
+ }
+ }
+ }
+
+ public void release() {
+ lock.unlock();
+ }
+}
diff --git a/client/src/main/java/ctbrec/ui/WebbrowserTab.java b/client/src/main/java/ctbrec/ui/WebbrowserTab.java
deleted file mode 100644
index cf904a3e..00000000
--- a/client/src/main/java/ctbrec/ui/WebbrowserTab.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package ctbrec.ui;
-
-import java.io.File;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import ctbrec.OS;
-import ctbrec.ui.controls.Dialogs;
-import javafx.scene.control.Tab;
-import javafx.scene.web.WebEngine;
-import javafx.scene.web.WebView;
-
-public class WebbrowserTab extends Tab {
-
- private static final transient Logger LOG = LoggerFactory.getLogger(WebbrowserTab.class);
-
- public WebbrowserTab(String uri) {
- WebView browser = new WebView();
- WebEngine webEngine = browser.getEngine();
- webEngine.setUserDataDirectory(new File(OS.getConfigDir(), "webengine"));
- webEngine.setJavaScriptEnabled(true);
- webEngine.load(uri);
- setContent(browser);
-
- webEngine.setOnError(evt -> {
- LOG.error("Couldn't load {}", uri, evt.getException());
- Dialogs.showError("Error", "Couldn't load " + uri, evt.getException());
- });
- }
-}
diff --git a/client/src/main/java/ctbrec/ui/sites/bonga/BongaCamsElectronLoginDialog.java b/client/src/main/java/ctbrec/ui/sites/bonga/BongaCamsElectronLoginDialog.java
new file mode 100644
index 00000000..82df391b
--- /dev/null
+++ b/client/src/main/java/ctbrec/ui/sites/bonga/BongaCamsElectronLoginDialog.java
@@ -0,0 +1,124 @@
+package ctbrec.ui.sites.bonga;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.Objects;
+import java.util.function.Consumer;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import ctbrec.Config;
+import ctbrec.sites.bonga.BongaCams;
+import ctbrec.ui.ExternalBrowser;
+import okhttp3.Cookie;
+import okhttp3.Cookie.Builder;
+import okhttp3.CookieJar;
+import okhttp3.HttpUrl;
+
+public class BongaCamsElectronLoginDialog {
+
+ private static final transient Logger LOG = LoggerFactory.getLogger(BongaCamsElectronLoginDialog.class);
+ public static final String DOMAIN = "bongacams.com";
+ public static final String URL = BongaCams.BASE_URL + "/login";
+ private CookieJar cookieJar;
+ private ExternalBrowser browser;
+
+ public BongaCamsElectronLoginDialog(CookieJar cookieJar) throws IOException {
+ this.cookieJar = cookieJar;
+ browser = ExternalBrowser.getInstance();
+ try {
+ JSONObject config = new JSONObject();
+ config.put("url", URL);
+ config.put("w", 640);
+ config.put("h", 480);
+ JSONObject msg = new JSONObject();
+ msg.put("config", config);
+ browser.run(msg.toString(), msgHandler);
+ } catch (InterruptedException e) {
+ throw new IOException("Couldn't wait for login dialog", e);
+ } finally {
+ browser.close();
+ browser.release();
+ }
+ }
+
+ private Consumer msgHandler = (line) -> {
+ if(!line.startsWith("{")) {
+ System.err.println(line);
+ } else {
+ JSONObject json = new JSONObject(line);
+ //LOG.debug("Browser: {}", json.toString(2));
+ if(json.has("url")) {
+ String url = json.getString("url");
+ if(url.endsWith("/login")) {
+ try {
+ Thread.sleep(500);
+ String username = Config.getInstance().getSettings().bongaUsername;
+ if (username != null && !username.trim().isEmpty()) {
+ browser.executeJavaScript("$('input[name=\"log_in[username]\"]').attr('value','" + username + "')");
+ }
+ String password = Config.getInstance().getSettings().bongaPassword;
+ if (password != null && !password.trim().isEmpty()) {
+ browser.executeJavaScript("$('input[name=\"log_in[password]\"]').attr('value','" + password + "')");
+ }
+ String[] simplify = new String[] {
+ "$('div#header').css('display','none');",
+ "$('div.footer').css('display','none');",
+ "$('div.footer_copy').css('display','none')",
+ "$('div[class~=\"banner_top_index\"]').css('display','none');",
+ "$('td.menu_container').css('display','none');",
+ "$('div[class~=\"fancybox-overlay\"]').css('display','none');"
+ };
+ for (String js : simplify) {
+ browser.executeJavaScript(js);
+ }
+ } catch(Exception e) {
+ LOG.warn("Couldn't auto fill username and password for BongaCams", e);
+ }
+ }
+
+ if(json.has("cookies")) {
+ JSONArray _cookies = json.getJSONArray("cookies");
+ for (int i = 0; i < _cookies.length(); i++) {
+ JSONObject cookie = _cookies.getJSONObject(i);
+ if(cookie.getString("domain").contains(DOMAIN)) {
+ Builder b = new Cookie.Builder()
+ .path(cookie.getString("path"))
+ .domain(DOMAIN)
+ .name(cookie.getString("name"))
+ .value(cookie.getString("value"))
+ .expiresAt(Double.valueOf(cookie.optDouble("expirationDate")).longValue());
+ if(cookie.optBoolean("hostOnly")) {
+ b.hostOnlyDomain(DOMAIN);
+ }
+ if(cookie.optBoolean("httpOnly")) {
+ b.httpOnly();
+ }
+ if(cookie.optBoolean("secure")) {
+ b.secure();
+ }
+ Cookie c = b.build();
+ cookieJar.saveFromResponse(HttpUrl.parse(BongaCams.BASE_URL), Collections.singletonList(c));
+ }
+ }
+ }
+
+ try {
+ URL _url = new URL(url);
+ if (Objects.equals(_url.getPath(), "/")) {
+ browser.close();
+ }
+ } catch (MalformedURLException e) {
+ LOG.error("Couldn't parse new url {}", url, e);
+ } catch (IOException e) {
+ LOG.error("Couldn't send shutdown request to external browser", e);
+ }
+ }
+ }
+ };
+}
diff --git a/client/src/main/java/ctbrec/ui/sites/bonga/BongaCamsLoginDialog.java b/client/src/main/java/ctbrec/ui/sites/bonga/BongaCamsLoginDialog.java
deleted file mode 100644
index 099d0c7c..00000000
--- a/client/src/main/java/ctbrec/ui/sites/bonga/BongaCamsLoginDialog.java
+++ /dev/null
@@ -1,120 +0,0 @@
-package ctbrec.ui.sites.bonga;
-
-import java.io.File;
-import java.io.InputStream;
-import java.net.CookieHandler;
-import java.net.CookieManager;
-import java.net.HttpCookie;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.List;
-import java.util.Objects;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import ctbrec.Config;
-import ctbrec.OS;
-import ctbrec.sites.bonga.BongaCams;
-import javafx.concurrent.Worker.State;
-import javafx.scene.Scene;
-import javafx.scene.control.ProgressIndicator;
-import javafx.scene.image.Image;
-import javafx.scene.layout.Region;
-import javafx.scene.layout.StackPane;
-import javafx.scene.web.WebEngine;
-import javafx.scene.web.WebView;
-import javafx.stage.Stage;
-
-public class BongaCamsLoginDialog {
-
- private static final transient Logger LOG = LoggerFactory.getLogger(BongaCamsLoginDialog.class);
- public static final String URL = BongaCams.BASE_URL + "/login";
- private List cookies = null;
- private String url;
- private Region veil;
- private ProgressIndicator p;
-
- public BongaCamsLoginDialog() {
- Stage stage = new Stage();
- stage.setTitle("BongaCams Login");
- InputStream icon = getClass().getResourceAsStream("/icon.png");
- stage.getIcons().add(new Image(icon));
- CookieManager cookieManager = new CookieManager();
- CookieHandler.setDefault(cookieManager);
- WebView webView = createWebView(stage);
-
- veil = new Region();
- veil.setStyle("-fx-background-color: rgba(0, 0, 0, 0.4)");
- p = new ProgressIndicator();
- p.setMaxSize(140, 140);
-
- StackPane stackPane = new StackPane();
- stackPane.getChildren().addAll(webView, veil, p);
-
- stage.setScene(new Scene(stackPane, 640, 480));
- stage.showAndWait();
- cookies = cookieManager.getCookieStore().getCookies();
- }
-
- private WebView createWebView(Stage stage) {
- WebView browser = new WebView();
- WebEngine webEngine = browser.getEngine();
- webEngine.setJavaScriptEnabled(true);
- webEngine.setUserAgent(Config.getInstance().getSettings().httpUserAgent);
- webEngine.locationProperty().addListener((obs, oldV, newV) -> {
- try {
- URL _url = new URL(newV);
- if (Objects.equals(_url.getPath(), "/")) {
- stage.close();
- }
- } catch (MalformedURLException e) {
- LOG.error("Couldn't parse new url {}", newV, e);
- }
- url = newV.toString();
- });
- webEngine.getLoadWorker().stateProperty().addListener((observable, oldState, newState) -> {
- if (newState == State.SUCCEEDED) {
- veil.setVisible(false);
- p.setVisible(false);
- //System.out.println("############# " + webEngine.getLocation());
- //System.out.println(webEngine.getDocument().getDocumentElement().getTextContent());
- try {
- String username = Config.getInstance().getSettings().bongaUsername;
- if (username != null && !username.trim().isEmpty()) {
- webEngine.executeScript("$('input[name=\"log_in[username]\"]').attr('value','" + username + "')");
- }
- String password = Config.getInstance().getSettings().bongaPassword;
- if (password != null && !password.trim().isEmpty()) {
- webEngine.executeScript("$('input[name=\"log_in[password]\"]').attr('value','" + password + "')");
- }
- webEngine.executeScript("$('div[class~=\"fancybox-overlay\"]').css('display','none')");
- webEngine.executeScript("$('div#header').css('display','none')");
- webEngine.executeScript("$('div.footer').css('display','none')");
- webEngine.executeScript("$('div.footer_copy').css('display','none')");
- webEngine.executeScript("$('div[class~=\"banner_top_index\"]').css('display','none')");
- webEngine.executeScript("$('td.menu_container').css('display','none')");
- } catch(Exception e) {
- LOG.warn("Couldn't auto fill username and password for BongaCams", e);
- }
- } else if (newState == State.CANCELLED || newState == State.FAILED) {
- veil.setVisible(false);
- p.setVisible(false);
- }
- });
- webEngine.setUserDataDirectory(new File(OS.getConfigDir(), "webengine"));
- webEngine.load(URL);
- return browser;
- }
-
- public List getCookies() {
- // for (HttpCookie httpCookie : cookies) {
- // LOG.debug("Cookie: {}", httpCookie);
- // }
- return cookies;
- }
-
- public String getUrl() {
- return url;
- }
-}
diff --git a/client/src/main/java/ctbrec/ui/sites/bonga/BongaCamsSiteUi.java b/client/src/main/java/ctbrec/ui/sites/bonga/BongaCamsSiteUi.java
index 8e123696..46a6b1f3 100644
--- a/client/src/main/java/ctbrec/ui/sites/bonga/BongaCamsSiteUi.java
+++ b/client/src/main/java/ctbrec/ui/sites/bonga/BongaCamsSiteUi.java
@@ -1,9 +1,6 @@
package ctbrec.ui.sites.bonga;
import java.io.IOException;
-import java.net.HttpCookie;
-import java.util.ArrayList;
-import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
@@ -15,10 +12,6 @@ import ctbrec.sites.bonga.BongaCams;
import ctbrec.sites.bonga.BongaCamsHttpClient;
import ctbrec.ui.SiteUI;
import ctbrec.ui.TabProvider;
-import javafx.application.Platform;
-import okhttp3.Cookie;
-import okhttp3.CookieJar;
-import okhttp3.HttpUrl;
public class BongaCamsSiteUi implements SiteUI {
@@ -50,31 +43,25 @@ public class BongaCamsSiteUi implements SiteUI {
return true;
} else {
BlockingQueue queue = new LinkedBlockingQueue<>();
+ try {
+ new Thread(() -> {
+ // login with external browser window
+ try {
+ new BongaCamsElectronLoginDialog(bongaCams.getHttpClient().getCookieJar());
+ } catch (Exception e1) {
+ LOG.error("Error logging in with external browser", e1);
+ }
- Runnable showDialog = () -> {
- // login with javafx WebView
- BongaCamsLoginDialog loginDialog = new BongaCamsLoginDialog();
-
- // 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);
- }
+ try {
+ queue.put(true);
+ } catch (InterruptedException e) {
+ LOG.error("Error while signaling termination", e);
+ }
+ }).start();
+ queue.take();
+ } catch (InterruptedException e) {
+ LOG.error("Error while waiting for login dialog to close", e);
+ throw new IOException(e);
}
BongaCamsHttpClient httpClient = (BongaCamsHttpClient)bongaCams.getHttpClient();
@@ -87,26 +74,4 @@ public class BongaCamsSiteUi implements SiteUI {
return loggedIn;
}
}
-
-
- private void transferCookies(BongaCamsLoginDialog loginDialog) {
- BongaCamsHttpClient httpClient = (BongaCamsHttpClient)bongaCams.getHttpClient();
- CookieJar cookieJar = httpClient.getCookieJar();
-
- HttpUrl redirectedUrl = HttpUrl.parse(loginDialog.getUrl());
- List cookies = new ArrayList<>();
- for (HttpCookie webViewCookie : loginDialog.getCookies()) {
- Cookie cookie = Cookie.parse(redirectedUrl, webViewCookie.toString());
- cookies.add(cookie);
- }
- cookieJar.saveFromResponse(redirectedUrl, cookies);
-
- HttpUrl origUrl = HttpUrl.parse(BongaCamsLoginDialog.URL);
- cookies = new ArrayList<>();
- for (HttpCookie webViewCookie : loginDialog.getCookies()) {
- Cookie cookie = Cookie.parse(origUrl, webViewCookie.toString());
- cookies.add(cookie);
- }
- cookieJar.saveFromResponse(origUrl, cookies);
- }
}
diff --git a/client/src/main/java/ctbrec/ui/sites/cam4/Cam4ElectronLoginDialog.java b/client/src/main/java/ctbrec/ui/sites/cam4/Cam4ElectronLoginDialog.java
new file mode 100644
index 00000000..117849d0
--- /dev/null
+++ b/client/src/main/java/ctbrec/ui/sites/cam4/Cam4ElectronLoginDialog.java
@@ -0,0 +1,127 @@
+package ctbrec.ui.sites.cam4;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.Objects;
+import java.util.function.Consumer;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import ctbrec.Config;
+import ctbrec.sites.cam4.Cam4;
+import ctbrec.ui.ExternalBrowser;
+import okhttp3.Cookie;
+import okhttp3.Cookie.Builder;
+import okhttp3.CookieJar;
+import okhttp3.HttpUrl;
+
+public class Cam4ElectronLoginDialog {
+
+ private static final transient Logger LOG = LoggerFactory.getLogger(Cam4ElectronLoginDialog.class);
+ public static final String DOMAIN = "cam4.com";
+ public static final String URL = Cam4.BASE_URI + "/login";
+ private CookieJar cookieJar;
+ private ExternalBrowser browser;
+
+ public Cam4ElectronLoginDialog(CookieJar cookieJar) throws IOException {
+ this.cookieJar = cookieJar;
+ browser = ExternalBrowser.getInstance();
+ try {
+ JSONObject config = new JSONObject();
+ config.put("url", URL);
+ config.put("w", 480);
+ config.put("h", 640);
+ JSONObject msg = new JSONObject();
+ msg.put("config", config);
+ browser.run(msg.toString(), msgHandler);
+ } catch (InterruptedException e) {
+ throw new IOException("Couldn't wait for login dialog", e);
+ } finally {
+ browser.close();
+ browser.release();
+ }
+ }
+
+ private Consumer msgHandler = (line) -> {
+ if(!line.startsWith("{")) {
+ System.err.println(line);
+ } else {
+ JSONObject json = new JSONObject(line);
+ if(json.has("url")) {
+ String url = json.getString("url");
+
+ if(url.endsWith("/login")) {
+ try {
+ String username = Config.getInstance().getSettings().cam4Username;
+ if (username != null && !username.trim().isEmpty()) {
+ browser.executeJavaScript("document.querySelector('#loginPageForm input[name=\"username\"]').value = '" + username + "';");
+ }
+ String password = Config.getInstance().getSettings().cam4Password;
+ if (password != null && !password.trim().isEmpty()) {
+ browser.executeJavaScript("document.querySelector('#loginPageForm input[name=\"password\"]').value = '" + password + "';");
+ }
+ browser.executeJavaScript("document.getElementById('footer').setAttribute('style', 'display:none');");
+ browser.executeJavaScript("document.getElementById('promptArea').setAttribute('style', 'display:none');");
+ browser.executeJavaScript("document.getElementById('content').setAttribute('style', 'padding: 0');");
+ browser.executeJavaScript("document.querySelector('div[class~=\"navbar\"]').setAttribute('style', 'display:none');");
+ } catch(Exception e) {
+ LOG.warn("Couldn't auto fill username and password for Cam4", e);
+ }
+ }
+
+ if(json.has("cookies")) {
+ JSONArray _cookies = json.getJSONArray("cookies");
+ try {
+ URL _url = new URL(url);
+ for (int i = 0; i < _cookies.length(); i++) {
+ JSONObject cookie = _cookies.getJSONObject(i);
+ if(cookie.getString("domain").contains("cam4")) {
+ String domain = cookie.getString("domain");
+ if(domain.startsWith(".")) {
+ domain = domain.substring(1);
+ }
+ Cookie c = createCookie(domain, cookie);
+ cookieJar.saveFromResponse(HttpUrl.parse(url), Collections.singletonList(c));
+ c = createCookie("cam4.com", cookie);
+ cookieJar.saveFromResponse(HttpUrl.parse(Cam4.BASE_URI), Collections.singletonList(c));
+ }
+ }
+ if (Objects.equals(_url.getPath(), "/")) {
+ try {
+ browser.close();
+ } catch(IOException e) {
+ LOG.error("Couldn't send close request to browser", e);
+ }
+ }
+ } catch (MalformedURLException e) {
+ LOG.error("Couldn't parse new url {}", url, e);
+ }
+ }
+ }
+ }
+ };
+
+ private Cookie createCookie(String domain, JSONObject cookie) {
+ Builder b = new Cookie.Builder()
+ .path(cookie.getString("path"))
+ .domain(domain)
+ .name(cookie.getString("name"))
+ .value(cookie.getString("value"))
+ .expiresAt(Double.valueOf(cookie.optDouble("expirationDate")).longValue());
+ if(cookie.optBoolean("hostOnly")) {
+ b.hostOnlyDomain(domain);
+ }
+ if(cookie.optBoolean("httpOnly")) {
+ b.httpOnly();
+ }
+ if(cookie.optBoolean("secure")) {
+ b.secure();
+ }
+ return b.build();
+ }
+}
diff --git a/client/src/main/java/ctbrec/ui/sites/cam4/Cam4LoginDialog.java b/client/src/main/java/ctbrec/ui/sites/cam4/Cam4LoginDialog.java
deleted file mode 100644
index 65c13019..00000000
--- a/client/src/main/java/ctbrec/ui/sites/cam4/Cam4LoginDialog.java
+++ /dev/null
@@ -1,112 +0,0 @@
-package ctbrec.ui.sites.cam4;
-
-import java.io.File;
-import java.io.InputStream;
-import java.net.CookieHandler;
-import java.net.CookieManager;
-import java.net.HttpCookie;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.List;
-import java.util.Objects;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import ctbrec.Config;
-import ctbrec.OS;
-import ctbrec.sites.cam4.Cam4;
-import javafx.concurrent.Worker.State;
-import javafx.scene.Scene;
-import javafx.scene.control.ProgressIndicator;
-import javafx.scene.image.Image;
-import javafx.scene.layout.Region;
-import javafx.scene.layout.StackPane;
-import javafx.scene.web.WebEngine;
-import javafx.scene.web.WebView;
-import javafx.stage.Stage;
-
-public class Cam4LoginDialog {
-
- private static final transient Logger LOG = LoggerFactory.getLogger(Cam4LoginDialog.class);
- public static final String URL = Cam4.BASE_URI + "/login";
- private List cookies = null;
- private String url;
- private Region veil;
- private ProgressIndicator p;
-
- public Cam4LoginDialog() {
- Stage stage = new Stage();
- stage.setTitle("Cam4 Login");
- InputStream icon = getClass().getResourceAsStream("/icon.png");
- stage.getIcons().add(new Image(icon));
- CookieManager cookieManager = new CookieManager();
- CookieHandler.setDefault(cookieManager);
- WebView webView = createWebView(stage);
-
- veil = new Region();
- veil.setStyle("-fx-background-color: rgba(0, 0, 0, 0.4)");
- p = new ProgressIndicator();
- p.setMaxSize(140, 140);
-
- StackPane stackPane = new StackPane();
- stackPane.getChildren().addAll(webView, veil, p);
-
- stage.setScene(new Scene(stackPane, 480, 854));
- stage.showAndWait();
- cookies = cookieManager.getCookieStore().getCookies();
- }
-
- private WebView createWebView(Stage stage) {
- WebView browser = new WebView();
- WebEngine webEngine = browser.getEngine();
- webEngine.setJavaScriptEnabled(true);
- webEngine.setUserAgent(Config.getInstance().getSettings().httpUserAgent);
- webEngine.locationProperty().addListener((obs, oldV, newV) -> {
- try {
- URL _url = new URL(newV);
- if (Objects.equals(_url.getPath(), "/")) {
- stage.close();
- }
- } catch (MalformedURLException e) {
- LOG.error("Couldn't parse new url {}", newV, e);
- }
- url = newV.toString();
- });
- webEngine.getLoadWorker().stateProperty().addListener((observable, oldState, newState) -> {
- if (newState == State.SUCCEEDED) {
- veil.setVisible(false);
- p.setVisible(false);
- try {
- String username = Config.getInstance().getSettings().cam4Username;
- if (username != null && !username.trim().isEmpty()) {
- webEngine.executeScript("$('input[name=username]').attr('value','" + username + "')");
- }
- String password = Config.getInstance().getSettings().cam4Password;
- if (password != null && !password.trim().isEmpty()) {
- webEngine.executeScript("$('input[name=password]').attr('value','" + password + "')");
- }
- webEngine.executeScript("$('div[class~=navbar]').css('display','none')");
- webEngine.executeScript("$('div#footer').css('display','none')");
- webEngine.executeScript("$('div#content').css('padding','0')");
- } catch(Exception e) {
- LOG.warn("Couldn't auto fill username and password for Cam4", e);
- }
- } else if (newState == State.CANCELLED || newState == State.FAILED) {
- veil.setVisible(false);
- p.setVisible(false);
- }
- });
- webEngine.setUserDataDirectory(new File(OS.getConfigDir(), "webengine"));
- webEngine.load(URL);
- return browser;
- }
-
- public List getCookies() {
- return cookies;
- }
-
- public String getUrl() {
- return url;
- }
-}
diff --git a/client/src/main/java/ctbrec/ui/sites/cam4/Cam4SiteUi.java b/client/src/main/java/ctbrec/ui/sites/cam4/Cam4SiteUi.java
index 8e61b411..fbc18c81 100644
--- a/client/src/main/java/ctbrec/ui/sites/cam4/Cam4SiteUi.java
+++ b/client/src/main/java/ctbrec/ui/sites/cam4/Cam4SiteUi.java
@@ -1,9 +1,6 @@
package ctbrec.ui.sites.cam4;
import java.io.IOException;
-import java.net.HttpCookie;
-import java.util.ArrayList;
-import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
@@ -16,9 +13,6 @@ import ctbrec.sites.cam4.Cam4HttpClient;
import ctbrec.ui.SiteUI;
import ctbrec.ui.TabProvider;
import javafx.application.Platform;
-import okhttp3.Cookie;
-import okhttp3.CookieJar;
-import okhttp3.HttpUrl;
public class Cam4SiteUi implements SiteUI {
private static final transient Logger LOG = LoggerFactory.getLogger(Cam4SiteUi.class);
@@ -46,18 +40,19 @@ public class Cam4SiteUi implements SiteUI {
@Override
public synchronized boolean login() throws IOException {
boolean automaticLogin = cam4.login();
- if(automaticLogin) {
+ if (automaticLogin) {
return true;
} else {
BlockingQueue queue = new LinkedBlockingQueue<>();
Runnable showDialog = () -> {
- // login with javafx WebView
- Cam4LoginDialog loginDialog = new Cam4LoginDialog();
-
- // transfer cookies from WebView to OkHttp cookie jar
- transferCookies(loginDialog);
+ // login with external browser
+ try {
+ new Cam4ElectronLoginDialog(cam4.getHttpClient().getCookieJar());
+ } catch (Exception e1) {
+ LOG.error("Error logging in with external browser", e1);
+ }
try {
queue.put(true);
@@ -66,16 +61,12 @@ public class Cam4SiteUi implements SiteUI {
}
};
- 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);
- }
+ Platform.runLater(showDialog);
+ try {
+ queue.take();
+ } catch (InterruptedException e) {
+ LOG.error("Error while waiting for login dialog to close", e);
+ throw new IOException(e);
}
Cam4HttpClient httpClient = (Cam4HttpClient) cam4.getHttpClient();
@@ -83,31 +74,4 @@ public class Cam4SiteUi implements SiteUI {
return loggedIn;
}
}
-
-
- private void transferCookies(Cam4LoginDialog loginDialog) {
- Cam4HttpClient httpClient = (Cam4HttpClient) cam4.getHttpClient();
- CookieJar cookieJar = httpClient.getCookieJar();
-
- HttpUrl redirectedUrl = HttpUrl.parse(loginDialog.getUrl());
- List cookies = new ArrayList<>();
- for (HttpCookie webViewCookie : loginDialog.getCookies()) {
- if(webViewCookie.getDomain().contains("cam4")) {
- Cookie cookie = Cookie.parse(redirectedUrl, webViewCookie.toString());
- LOG.debug("{} {} {}", webViewCookie.getDomain(), webViewCookie.getName(), webViewCookie.getValue());
- cookies.add(cookie);
- }
- }
- cookieJar.saveFromResponse(redirectedUrl, cookies);
-
- HttpUrl origUrl = HttpUrl.parse(Cam4LoginDialog.URL);
- cookies = new ArrayList<>();
- for (HttpCookie webViewCookie : loginDialog.getCookies()) {
- if(webViewCookie.getDomain().contains("cam4")) {
- Cookie cookie = Cookie.parse(origUrl, webViewCookie.toString());
- cookies.add(cookie);
- }
- }
- cookieJar.saveFromResponse(origUrl, cookies);
- }
}
diff --git a/client/src/main/java/ctbrec/ui/sites/camsoda/CamsodaLoginDialog.java b/client/src/main/java/ctbrec/ui/sites/camsoda/CamsodaLoginDialog.java
deleted file mode 100644
index e08731ea..00000000
--- a/client/src/main/java/ctbrec/ui/sites/camsoda/CamsodaLoginDialog.java
+++ /dev/null
@@ -1,110 +0,0 @@
-package ctbrec.ui.sites.camsoda;
-
-import java.io.File;
-import java.io.InputStream;
-import java.net.CookieHandler;
-import java.net.CookieManager;
-import java.net.HttpCookie;
-import java.util.Base64;
-import java.util.List;
-
-import ctbrec.OS;
-import ctbrec.sites.camsoda.Camsoda;
-import javafx.concurrent.Worker.State;
-import javafx.scene.Scene;
-import javafx.scene.control.ProgressIndicator;
-import javafx.scene.image.Image;
-import javafx.scene.layout.Region;
-import javafx.scene.layout.StackPane;
-import javafx.scene.web.WebEngine;
-import javafx.scene.web.WebView;
-import javafx.stage.Stage;
-
-// FIXME this dialog does not help, because google's recaptcha does not work
-// with WebView even though it does work in Cam4LoginDialog
-public class CamsodaLoginDialog {
-
- public static final String URL = Camsoda.BASE_URI;
- private List cookies = null;
- private String url;
- private Region veil;
- private ProgressIndicator p;
-
- public CamsodaLoginDialog() {
- Stage stage = new Stage();
- stage.setTitle("CamSoda Login");
- InputStream icon = getClass().getResourceAsStream("/icon.png");
- stage.getIcons().add(new Image(icon));
- CookieManager cookieManager = new CookieManager();
- CookieHandler.setDefault(cookieManager);
- WebView webView = createWebView(stage);
-
- veil = new Region();
- veil.setStyle("-fx-background-color: rgba(1, 1, 1)");
- p = new ProgressIndicator();
- p.setMaxSize(140, 140);
-
- p.setVisible(true);
- veil.visibleProperty().bind(p.visibleProperty());
-
- StackPane stackPane = new StackPane();
- stackPane.getChildren().addAll(webView, veil, p);
-
- stage.setScene(new Scene(stackPane, 400, 358));
- stage.showAndWait();
- cookies = cookieManager.getCookieStore().getCookies();
- }
-
- private WebView createWebView(Stage stage) {
- WebView browser = new WebView();
- WebEngine webEngine = browser.getEngine();
- webEngine.setJavaScriptEnabled(true);
- webEngine.locationProperty().addListener((obs, oldV, newV) -> {
- // try {
- // URL _url = new URL(newV);
- // if (Objects.equals(_url.getPath(), "/")) {
- // stage.close();
- // }
- // } catch (MalformedURLException e) {
- // LOG.error("Couldn't parse new url {}", newV, e);
- // }
- url = newV.toString();
- System.out.println(newV.toString());
- });
- webEngine.getLoadWorker().stateProperty().addListener((observable, oldState, newState) -> {
- if (newState == State.SUCCEEDED) {
- webEngine.executeScript("document.querySelector('a[ng-click=\"signin();\"]').click()");
- p.setVisible(false);
-
- // TODO make this work
- // String username = Config.getInstance().getSettings().camsodaUsername;
- // if (username != null && !username.trim().isEmpty()) {
- // webEngine.executeScript("document.querySelector('input[name=\"loginUsername\"]').value = '" + username + "'");
- // }
- // String password = Config.getInstance().getSettings().camsodaPassword;
- // if (password != null && !password.trim().isEmpty()) {
- // webEngine.executeScript("document.querySelector('input[name=\"loginPassword\"]').value = '" + password + "'");
- // }
- } else if (newState == State.CANCELLED || newState == State.FAILED) {
- p.setVisible(false);
- }
- });
-
- webEngine.setUserStyleSheetLocation("data:text/css;base64," + Base64.getEncoder().encodeToString(CUSTOM_STYLE.getBytes()));
- webEngine.setUserDataDirectory(new File(OS.getConfigDir(), "webengine"));
- webEngine.load(URL);
- return browser;
- }
-
- public List getCookies() {
- return cookies;
- }
-
- public String getUrl() {
- return url;
- }
-
- private static final String CUSTOM_STYLE = ""
- + ".ngdialog.ngdialog-theme-custom { padding: 0 !important }"
- + ".ngdialog-overlay { background: black !important; }";
-}
diff --git a/client/src/main/java/ctbrec/ui/sites/camsoda/CamsodaSiteUi.java b/client/src/main/java/ctbrec/ui/sites/camsoda/CamsodaSiteUi.java
index af1be6ab..2b2a2eb7 100644
--- a/client/src/main/java/ctbrec/ui/sites/camsoda/CamsodaSiteUi.java
+++ b/client/src/main/java/ctbrec/ui/sites/camsoda/CamsodaSiteUi.java
@@ -1,24 +1,14 @@
package ctbrec.ui.sites.camsoda;
import java.io.IOException;
-import java.net.HttpCookie;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.LinkedBlockingQueue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ctbrec.sites.ConfigUI;
import ctbrec.sites.camsoda.Camsoda;
-import ctbrec.sites.camsoda.CamsodaHttpClient;
import ctbrec.ui.SiteUI;
import ctbrec.ui.TabProvider;
-import ctbrec.ui.sites.cam4.Cam4LoginDialog;
-import javafx.application.Platform;
-import okhttp3.Cookie;
-import okhttp3.HttpUrl;
public class CamsodaSiteUi implements SiteUI {
@@ -50,58 +40,57 @@ public class CamsodaSiteUi implements SiteUI {
return automaticLogin;
}
-
- @SuppressWarnings("unused")
- private boolean loginWithDialog() throws IOException {
- BlockingQueue queue = new LinkedBlockingQueue<>();
-
- Runnable showDialog = () -> {
- // login with javafx WebView
- 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 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(Cam4LoginDialog.URL);
- cookies = new ArrayList<>();
- for (HttpCookie webViewCookie : loginDialog.getCookies()) {
- Cookie cookie = Cookie.parse(origUrl, webViewCookie.toString());
- cookies.add(cookie);
- }
- camsoda.getHttpClient().getCookieJar().saveFromResponse(origUrl, cookies);
- }
+ // @SuppressWarnings("unused")
+ // private boolean loginWithDialog() throws IOException {
+ // BlockingQueue 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 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);
+ // }
}
diff --git a/client/src/main/java/ctbrec/ui/sites/jasmin/LiveJasminConfigUi.java b/client/src/main/java/ctbrec/ui/sites/jasmin/LiveJasminConfigUi.java
index 2cf66c02..f1c8c8db 100644
--- a/client/src/main/java/ctbrec/ui/sites/jasmin/LiveJasminConfigUi.java
+++ b/client/src/main/java/ctbrec/ui/sites/jasmin/LiveJasminConfigUi.java
@@ -73,19 +73,20 @@ public class LiveJasminConfigUi extends AbstractConfigUI {
GridPane.setColumnSpan(password, 2);
layout.add(password, 1, row++);
- layout.add(new Label("LiveJasmin Session ID"), 0, row);
- TextField sessionId = new TextField();
- sessionId.setText(Config.getInstance().getSettings().livejasminSession);
- sessionId.textProperty().addListener((ob, o, n) -> {
- if(!n.equals(Config.getInstance().getSettings().livejasminSession)) {
- Config.getInstance().getSettings().livejasminSession = n;
- save();
- }
- });
- GridPane.setFillWidth(sessionId, true);
- GridPane.setHgrow(sessionId, Priority.ALWAYS);
- GridPane.setColumnSpan(sessionId, 2);
- layout.add(sessionId, 1, row++);
+ // layout.add(new Label("LiveJasmin Session ID"), 0, row);
+ // TextField sessionId = new TextField();
+ // sessionId.setText(Config.getInstance().getSettings().livejasminSession);
+ // sessionId.textProperty().addListener((ob, o, n) -> {
+ // if(!n.equals(Config.getInstance().getSettings().livejasminSession)) {
+ // Config.getInstance().getSettings().livejasminSession = n;
+ // save();
+ // }
+ // });
+ // GridPane.setFillWidth(sessionId, true);
+ // GridPane.setHgrow(sessionId, Priority.ALWAYS);
+ // GridPane.setColumnSpan(sessionId, 2);
+ // GridPane.setMargin(sessionId, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
+ // layout.add(sessionId, 1, row++);
Button createAccount = new Button("Create new Account");
createAccount.setOnAction((e) -> DesktopIntegration.open(liveJasmin.getAffiliateLink()));
@@ -93,7 +94,6 @@ public class LiveJasminConfigUi extends AbstractConfigUI {
GridPane.setColumnSpan(createAccount, 2);
GridPane.setMargin(username, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
GridPane.setMargin(password, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
- GridPane.setMargin(sessionId, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
GridPane.setMargin(createAccount, new Insets(0, 0, 0, SettingsTab.CHECKBOX_MARGIN));
username.setPrefWidth(300);
diff --git a/client/src/main/java/ctbrec/ui/sites/jasmin/LiveJasminElectronLoginDialog.java b/client/src/main/java/ctbrec/ui/sites/jasmin/LiveJasminElectronLoginDialog.java
new file mode 100644
index 00000000..86879d9e
--- /dev/null
+++ b/client/src/main/java/ctbrec/ui/sites/jasmin/LiveJasminElectronLoginDialog.java
@@ -0,0 +1,97 @@
+package ctbrec.ui.sites.jasmin;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.function.Consumer;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import ctbrec.Config;
+import ctbrec.sites.jasmin.LiveJasmin;
+import ctbrec.ui.ExternalBrowser;
+import okhttp3.Cookie;
+import okhttp3.Cookie.Builder;
+import okhttp3.CookieJar;
+import okhttp3.HttpUrl;
+
+public class LiveJasminElectronLoginDialog {
+
+ private static final transient Logger LOG = LoggerFactory.getLogger(LiveJasminElectronLoginDialog.class);
+ public static final String URL = LiveJasmin.BASE_URL + "/en/auth/login";
+ private CookieJar cookieJar;
+ private ExternalBrowser browser;
+
+ public LiveJasminElectronLoginDialog(CookieJar cookieJar) throws IOException {
+ this.cookieJar = cookieJar;
+ browser = ExternalBrowser.getInstance();
+ try {
+ JSONObject config = new JSONObject();
+ config.put("url", URL);
+ config.put("w", 640);
+ config.put("h", 720);
+ JSONObject msg = new JSONObject();
+ msg.put("config", config);
+ browser.run(msg.toString(), msgHandler);
+ } catch (InterruptedException e) {
+ throw new IOException("Couldn't wait for login dialog", e);
+ } finally {
+ browser.close();
+ browser.release();
+ }
+ }
+
+ private Consumer msgHandler = (line) -> {
+ //LOG.debug("Browser: {}", line);
+ if(!line.startsWith("{")) {
+ System.err.println(line);
+ } else {
+ JSONObject json = new JSONObject(line);
+ if(json.has("url")) {
+ String url = json.getString("url");
+ if(url.endsWith("/auth/login")) {
+ try {
+ String username = Config.getInstance().getSettings().livejasminUsername;
+ if (username != null && !username.trim().isEmpty()) {
+ browser.executeJavaScript("document.querySelector('#login_form input[name=\"username\"]').value = '" + username + "';");
+ }
+ String password = Config.getInstance().getSettings().livejasminPassword;
+ if (password != null && !password.trim().isEmpty()) {
+ browser.executeJavaScript("document.querySelector('#login_form input[name=\"password\"]').value = '" + password + "';");
+ }
+ browser.executeJavaScript("document.getElementById('header_container').setAttribute('style', 'display:none');");
+ browser.executeJavaScript("document.getElementById('footer').setAttribute('style', 'display:none');");
+ browser.executeJavaScript("document.getElementById('react-container').setAttribute('style', 'display:none');");
+ browser.executeJavaScript("document.getElementById('inner_container').setAttribute('style', 'padding: 0; margin: 1em');");
+ browser.executeJavaScript("document.querySelector('div[class~=\"content_box\"]').setAttribute('style', 'margin: 1em');");
+ } catch(Exception e) {
+ LOG.warn("Couldn't auto fill username and password", e);
+ }
+ }
+ if(json.has("cookies")) {
+ JSONArray _cookies = json.getJSONArray("cookies");
+ for (int i = 0; i < _cookies.length(); i++) {
+ JSONObject cookie = _cookies.getJSONObject(i);
+ Builder b = new Cookie.Builder()
+ .path("/")
+ .domain("livejasmin.com")
+ .name(cookie.getString("name"))
+ .value(cookie.getString("value"))
+ .expiresAt(0);
+ Cookie c = b.build();
+ cookieJar.saveFromResponse(HttpUrl.parse(LiveJasmin.BASE_URL), Collections.singletonList(c));
+ }
+ }
+ if(url.contains("/member/")) {
+ try {
+ browser.close();
+ } catch(IOException e) {
+ LOG.error("Couldn't send close request to browser", e);
+ }
+ }
+ }
+ }
+ };
+}
diff --git a/client/src/main/java/ctbrec/ui/sites/jasmin/LiveJasminFollowedUpdateService.java b/client/src/main/java/ctbrec/ui/sites/jasmin/LiveJasminFollowedUpdateService.java
index b0cf8089..a660344c 100644
--- a/client/src/main/java/ctbrec/ui/sites/jasmin/LiveJasminFollowedUpdateService.java
+++ b/client/src/main/java/ctbrec/ui/sites/jasmin/LiveJasminFollowedUpdateService.java
@@ -15,6 +15,7 @@ import ctbrec.io.HttpException;
import ctbrec.sites.jasmin.LiveJasmin;
import ctbrec.sites.jasmin.LiveJasminModel;
import ctbrec.ui.PaginatedScheduledService;
+import ctbrec.ui.SiteUiFactory;
import javafx.concurrent.Task;
import okhttp3.Request;
import okhttp3.Response;
@@ -37,6 +38,10 @@ public class LiveJasminFollowedUpdateService extends PaginatedScheduledService {
return new Task>() {
@Override
public List call() throws IOException {
+ boolean loggedIn = SiteUiFactory.getUi(liveJasmin).login();
+ if(!loggedIn) {
+ throw new RuntimeException("Couldn't login on livejasmin.com");
+ }
//String _url = url + ((page-1) * 36); // TODO find out how to switch pages
//LOG.debug("Fetching page {}", url);
Request request = new Request.Builder()
diff --git a/client/src/main/java/ctbrec/ui/sites/jasmin/LiveJasminLoginDialog.java b/client/src/main/java/ctbrec/ui/sites/jasmin/LiveJasminLoginDialog.java
deleted file mode 100644
index f6071d54..00000000
--- a/client/src/main/java/ctbrec/ui/sites/jasmin/LiveJasminLoginDialog.java
+++ /dev/null
@@ -1,170 +0,0 @@
-package ctbrec.ui.sites.jasmin;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.CookieHandler;
-import java.net.CookieManager;
-import java.net.HttpCookie;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.List;
-import java.util.Objects;
-
-import org.json.JSONObject;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import ctbrec.Config;
-import ctbrec.OS;
-import ctbrec.io.HttpException;
-import ctbrec.sites.jasmin.LiveJasmin;
-import javafx.concurrent.Worker.State;
-import javafx.scene.Scene;
-import javafx.scene.control.ProgressIndicator;
-import javafx.scene.image.Image;
-import javafx.scene.layout.Region;
-import javafx.scene.layout.StackPane;
-import javafx.scene.web.WebEngine;
-import javafx.scene.web.WebView;
-import javafx.stage.Stage;
-import okhttp3.Request;
-import okhttp3.Response;
-
-public class LiveJasminLoginDialog {
-
- private static final transient Logger LOG = LoggerFactory.getLogger(LiveJasminLoginDialog.class);
- public static final String URL = "https://m.livejasmin.com/en/list"; // #login-modal
- private List cookies = null;
- private String url;
- private Region veil;
- private ProgressIndicator p;
- private LiveJasmin liveJasmin;
-
- public LiveJasminLoginDialog(LiveJasmin liveJasmin) throws IOException {
- this.liveJasmin = liveJasmin;
- Stage stage = new Stage();
- stage.setTitle("LiveJasmin Login");
- InputStream icon = getClass().getResourceAsStream("/icon.png");
- stage.getIcons().add(new Image(icon));
- CookieManager cookieManager = new CookieManager();
- CookieHandler.setDefault(cookieManager);
- WebView webView = createWebView(stage);
-
- veil = new Region();
- veil.setStyle("-fx-background-color: rgba(0, 0, 0, 0.4)");
- p = new ProgressIndicator();
- p.setMaxSize(140, 140);
-
- StackPane stackPane = new StackPane();
- stackPane.getChildren().addAll(webView, veil, p);
-
- stage.setScene(new Scene(stackPane, 360, 480));
- stage.showAndWait();
- cookies = cookieManager.getCookieStore().getCookies();
- }
-
- private WebView createWebView(Stage stage) throws IOException {
-
-
- WebView browser = new WebView();
- WebEngine webEngine = browser.getEngine();
- webEngine.setJavaScriptEnabled(true);
- //webEngine.setUserAgent("Mozilla/5.0 (Android 9.0; Mobile; rv:63.0) Gecko/63.0 Firefox/63.0");
- webEngine.setUserAgent("Mozilla/5.0 (Mobile; rv:30.0) Gecko/20100101 Firefox/30.0");
- webEngine.locationProperty().addListener((obs, oldV, newV) -> {
- try {
- URL _url = new URL(newV);
- if (Objects.equals(_url.getPath(), "/")) {
- stage.close();
- }
- } catch (MalformedURLException e) {
- LOG.error("Couldn't parse new url {}", newV, e);
- }
- url = newV.toString();
- });
- webEngine.getLoadWorker().stateProperty().addListener((observable, oldState, newState) -> {
- if (newState == State.SUCCEEDED) {
- veil.setVisible(false);
- p.setVisible(false);
- // try {
- // //webEngine.executeScript("$('#eighteen-plus-modal').hide();");
- // //webEngine.executeScript("$('body').html('"+loginForm+"');");
- // //webEngine.executeScript("$('#listpage').append('"+loginForm+"');");
- // // webEngine.executeScript("$('#main-menu-button').click();");
- // // webEngine.executeScript("$('#login-menu').click();");
- // String username = Config.getInstance().getSettings().livejasminUsername;
- // if (username != null && !username.trim().isEmpty()) {
- // webEngine.executeScript("$('#username').attr('value','" + username + "')");
- // }
- // String password = Config.getInstance().getSettings().livejasminPassword;
- // if (password != null && !password.trim().isEmpty()) {
- // webEngine.executeScript("$('#password').attr('value','" + password + "')");
- // }
- // } catch(Exception e) {
- // LOG.warn("Couldn't auto fill username and password for LiveJasmin", e);
- // }
- } else if (newState == State.CANCELLED || newState == State.FAILED) {
- veil.setVisible(false);
- p.setVisible(false);
- }
- });
- webEngine.setUserDataDirectory(new File(OS.getConfigDir(), "webengine"));
- webEngine.load(URL);
- return browser;
- }
-
- private String getLoginForm() throws IOException {
- callBaseUrl(); // to get cookies
- String url = "https://m.livejasmin.com/en/auth/window/get-login-window?isAjax=1";
- Request request = new Request.Builder()
- .url(url)
- .addHeader("User-Agent", "Mozilla/5.0 (Android 9.0; Mobile; rv:63.0) Gecko/63.0 Firefox/63.0")
- .addHeader("Accept", "application/json, text/javascript, */*")
- .addHeader("Accept-Language", "en")
- .addHeader("Referer", LiveJasmin.BASE_URL)
- .addHeader("X-Requested-With", "XMLHttpRequest")
- .build();
- try(Response response = liveJasmin.getHttpClient().execute(request)) {
- if(response.isSuccessful()) {
- String body = response.body().string();
- JSONObject json = new JSONObject(body);
- System.out.println(json.toString(2));
- if(json.optBoolean("success")) {
- JSONObject data = json.getJSONObject("data");
- return data.getString("content");
- } else {
- throw new IOException("Request was not successful: " + body);
- }
- } else {
- throw new HttpException(response.code(), response.message());
- }
- }
- }
-
- private void callBaseUrl() throws IOException {
- String url = liveJasmin.getBaseUrl();
- Request request = new Request.Builder()
- .url(url)
- .header("User-Agent", Config.getInstance().getSettings().httpUserAgent)
- .build();
- try(Response response = liveJasmin.getHttpClient().execute(request)) {
- if(response.isSuccessful()) {
-
- } else {
- throw new HttpException(response.code(), response.message());
- }
- }
- }
-
- public List getCookies() {
- for (HttpCookie httpCookie : cookies) {
- LOG.debug("Cookie: {}", httpCookie);
- }
- return cookies;
- }
-
- public String getUrl() {
- return url;
- }
-}
diff --git a/client/src/main/java/ctbrec/ui/sites/jasmin/LiveJasminSiteUi.java b/client/src/main/java/ctbrec/ui/sites/jasmin/LiveJasminSiteUi.java
index f0115555..10f20ab8 100644
--- a/client/src/main/java/ctbrec/ui/sites/jasmin/LiveJasminSiteUi.java
+++ b/client/src/main/java/ctbrec/ui/sites/jasmin/LiveJasminSiteUi.java
@@ -1,9 +1,8 @@
package ctbrec.ui.sites.jasmin;
import java.io.IOException;
-import java.net.HttpCookie;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -13,9 +12,6 @@ import ctbrec.sites.jasmin.LiveJasmin;
import ctbrec.sites.jasmin.LiveJasminHttpClient;
import ctbrec.ui.SiteUI;
import ctbrec.ui.TabProvider;
-import okhttp3.Cookie;
-import okhttp3.CookieJar;
-import okhttp3.HttpUrl;
public class LiveJasminSiteUi implements SiteUI {
@@ -28,12 +24,6 @@ public class LiveJasminSiteUi implements SiteUI {
this.liveJasmin = liveJasmin;
tabProvider = new LiveJasminTabProvider(liveJasmin);
configUi = new LiveJasminConfigUi(liveJasmin);
- try {
- login();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
}
@Override
@@ -49,74 +39,42 @@ public class LiveJasminSiteUi implements SiteUI {
@Override
public synchronized boolean login() throws IOException {
boolean automaticLogin = liveJasmin.login();
- return automaticLogin;
- // if(automaticLogin) {
- // return true;
- // } else {
- // BlockingQueue queue = new LinkedBlockingQueue<>();
- //
- // Runnable showDialog = () -> {
- // // login with javafx WebView
- // LiveJasminLoginDialog loginDialog;
- // try {
- // loginDialog = new LiveJasminLoginDialog(liveJasmin);
- // // transfer cookies from WebView to OkHttp cookie jar
- // transferCookies(loginDialog);
- // } catch (IOException e1) {
- // LOG.error("Couldn't load login dialog", e1);
- // }
- //
- // 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);
- // }
- // }
- //
- // LiveJasminHttpClient httpClient = (LiveJasminHttpClient)liveJasmin.getHttpClient();
- // boolean loggedIn = httpClient.checkLoginSuccess();
- // if(loggedIn) {
- // LOG.info("Logged in.");
- // } else {
- // LOG.info("Login failed");
- // }
- // return loggedIn;
- // }
- }
+ if(automaticLogin) {
+ return true;
+ } else {
+ BlockingQueue queue = new LinkedBlockingQueue<>();
- private void transferCookies(LiveJasminLoginDialog loginDialog) {
- LiveJasminHttpClient httpClient = (LiveJasminHttpClient)liveJasmin.getHttpClient();
- CookieJar cookieJar = httpClient.getCookieJar();
+ new Thread (() -> {
+ // login with external browser window
+ try {
+ //LiveJasminElectronLoginDialog dialog =
+ new LiveJasminElectronLoginDialog(liveJasmin.getHttpClient().getCookieJar());
+ } catch (IOException e1) {
+ LOG.error("Error logging in with external browser", e1);
+ }
- String[] urls = {
- "https://www.livejasmin.com",
- "http://www.livejasmin.com",
- "https://m.livejasmin.com",
- "http://m.livejasmin.com",
- "https://livejasmin.com",
- "http://livejasmin.com"
- };
+ try {
+ queue.put(true);
+ } catch (InterruptedException e) {
+ LOG.error("Error while signaling termination", e);
+ }
+ }).start();
- for (String u : urls) {
- HttpUrl url = HttpUrl.parse(u);
- List cookies = new ArrayList<>();
- for (HttpCookie webViewCookie : loginDialog.getCookies()) {
- Cookie cookie = Cookie.parse(url, webViewCookie.toString());
- cookies.add(cookie);
+ try {
+ queue.take();
+ } catch (InterruptedException e) {
+ LOG.error("Error while waiting for login dialog to close", e);
+ throw new IOException(e);
}
- cookieJar.saveFromResponse(url, cookies);
+
+ LiveJasminHttpClient httpClient = (LiveJasminHttpClient)liveJasmin.getHttpClient();
+ boolean loggedIn = httpClient.checkLoginSuccess();
+ if(loggedIn) {
+ LOG.info("Logged in");
+ } else {
+ LOG.info("Login failed");
+ }
+ return loggedIn;
}
}
}
diff --git a/client/src/main/java/ctbrec/ui/sites/jasmin/LiveJasminTabProvider.java b/client/src/main/java/ctbrec/ui/sites/jasmin/LiveJasminTabProvider.java
index 998c2ba7..ee135d5d 100644
--- a/client/src/main/java/ctbrec/ui/sites/jasmin/LiveJasminTabProvider.java
+++ b/client/src/main/java/ctbrec/ui/sites/jasmin/LiveJasminTabProvider.java
@@ -8,6 +8,7 @@ import ctbrec.ui.TabProvider;
import ctbrec.ui.ThumbOverviewTab;
import javafx.scene.Scene;
import javafx.scene.control.Tab;
+import javafx.util.Duration;
public class LiveJasminTabProvider extends TabProvider {
@@ -43,6 +44,7 @@ public class LiveJasminTabProvider extends TabProvider {
LiveJasminUpdateService s = new LiveJasminUpdateService(liveJasmin, url);
ThumbOverviewTab tab = new ThumbOverviewTab(title, s, liveJasmin);
tab.setRecorder(liveJasmin.getRecorder());
+ s.setPeriod(Duration.seconds(60));
return tab;
}
}
diff --git a/client/src/main/java/ctbrec/ui/sites/jasmin/LiveJasminUpdateService.java b/client/src/main/java/ctbrec/ui/sites/jasmin/LiveJasminUpdateService.java
index e810fcab..e19a3b3d 100644
--- a/client/src/main/java/ctbrec/ui/sites/jasmin/LiveJasminUpdateService.java
+++ b/client/src/main/java/ctbrec/ui/sites/jasmin/LiveJasminUpdateService.java
@@ -48,7 +48,7 @@ public class LiveJasminUpdateService extends PaginatedScheduledService {
.name("listPageOrderType")
.value("most_popular")
.build();
- cookieJar.saveFromResponse(HttpUrl.parse("https://www.livejasmin.com"), Collections.singletonList(sortCookie));
+ cookieJar.saveFromResponse(HttpUrl.parse("https://livejasmin.com"), Collections.singletonList(sortCookie));
LOG.debug("Fetching page {}", url);
Request request = new Request.Builder()
@@ -56,7 +56,7 @@ public class LiveJasminUpdateService extends PaginatedScheduledService {
.addHeader("User-Agent", Config.getInstance().getSettings().httpUserAgent)
.addHeader("Accept", "application/json, text/javascript, */*")
.addHeader("Accept-Language", "en")
- .addHeader("Referer", liveJasmin.getBaseUrl())
+ .addHeader("Referer", liveJasmin.getBaseUrl() + "/en/girls/")
.addHeader("X-Requested-With", "XMLHttpRequest")
.build();
try (Response response = liveJasmin.getHttpClient().execute(request)) {
diff --git a/common/pom.xml b/common/pom.xml
index 4308d633..8242591a 100644
--- a/common/pom.xml
+++ b/common/pom.xml
@@ -57,7 +57,7 @@
org.openjfx
- javafx-web
+ javafx-media
provided
diff --git a/common/src/main/java/ctbrec/OS.java b/common/src/main/java/ctbrec/OS.java
index e86842e4..268e8cbf 100644
--- a/common/src/main/java/ctbrec/OS.java
+++ b/common/src/main/java/ctbrec/OS.java
@@ -8,8 +8,11 @@ import java.awt.TrayIcon;
import java.awt.TrayIcon.MessageType;
import java.io.File;
import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.Arrays;
import java.util.Map.Entry;
import org.slf4j.Logger;
@@ -61,6 +64,46 @@ public class OS {
return configDir;
}
+ public static String[] getBrowserCommand(String...args) {
+ if(System.getenv("CTBREC_BROWSER") != null) {
+ String cmd[] = new String[args.length + 1];
+ cmd[0] = System.getenv("CTBREC_BROWSER");
+ System.arraycopy(args, 0, cmd, 1, args.length);
+ return cmd;
+ }
+
+ try {
+ URI uri = OS.class.getProtectionDomain().getCodeSource().getLocation().toURI();
+ File jar = new File(uri.getPath());
+ File browserDir = new File(jar.getParentFile(), "browser");
+ String[] cmd;
+ switch (getOsType()) {
+ case LINUX:
+ cmd = new String[args.length + 1];
+ cmd[0] = new File(browserDir, "ctbrec-minimal-browser").getAbsolutePath();
+ System.arraycopy(args, 0, cmd, 1, args.length);
+ break;
+ case WINDOWS:
+ cmd = new String[args.length + 1];
+ cmd[0] = new File(browserDir, "ctbrec-minimal-browser.exe").getAbsolutePath();
+ System.arraycopy(args, 0, cmd, 1, args.length);
+ break;
+ case MAC:
+ cmd = new String[args.length + 2];
+ cmd[0] = "open";
+ cmd[1] = new File(browserDir, "ctbrec-minimal-browser.app").getAbsolutePath();
+ System.arraycopy(args, 0, cmd, 2, args.length);
+ break;
+ default:
+ throw new RuntimeException("Unsupported operating system " + System.getProperty("os.name"));
+ }
+ LOG.debug("Browser command: {}", Arrays.toString(cmd));
+ return cmd;
+ } catch (URISyntaxException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
public static Settings getDefaultSettings() {
Settings settings = new Settings();
if(getOsType() == TYPE.WINDOWS) {
diff --git a/common/src/main/java/ctbrec/Settings.java b/common/src/main/java/ctbrec/Settings.java
index 649fb393..1e6612cf 100644
--- a/common/src/main/java/ctbrec/Settings.java
+++ b/common/src/main/java/ctbrec/Settings.java
@@ -36,6 +36,7 @@ public class Settings {
public boolean localRecording = true;
public int httpPort = 8080;
public int httpTimeout = 10000;
+ public String httpUserAgentMobile = "Mozilla/5.0 (Android 9.0; Mobile; rv:63.0) Gecko/63.0 Firefox/63.0";
public String httpUserAgent = "Mozilla/5.0 Gecko/20100101 Firefox/62.0";
public String httpServer = "localhost";
public String recordingsDir = System.getProperty("user.home") + File.separator + "ctbrec";
diff --git a/common/src/main/java/ctbrec/io/CookieJarImpl.java b/common/src/main/java/ctbrec/io/CookieJarImpl.java
index 69192ecb..324fb93a 100644
--- a/common/src/main/java/ctbrec/io/CookieJarImpl.java
+++ b/common/src/main/java/ctbrec/io/CookieJarImpl.java
@@ -25,7 +25,7 @@ public class CookieJarImpl implements CookieJar {
@Override
public void saveFromResponse(HttpUrl url, List cookies) {
- String host = getHost(url);
+ String host = getDomain(url);
List cookiesForUrl = cookieStore.get(host);
if (cookiesForUrl != null) {
cookiesForUrl = new ArrayList(cookiesForUrl); //unmodifiable
@@ -52,7 +52,7 @@ public class CookieJarImpl implements CookieJar {
@Override
public List loadForRequest(HttpUrl url) {
- String host = getHost(url);
+ String host = getDomain(url);
List cookies = cookieStore.get(host);
LOG.debug("Cookies for {}", url);
Optional.ofNullable(cookies).ifPresent(cookiez -> cookiez.forEach(c -> {
@@ -72,12 +72,13 @@ public class CookieJarImpl implements CookieJar {
throw new NoSuchElementException("No cookie named " + name + " for " + url.host() + " available");
}
- private String getHost(HttpUrl url) {
- String host = url.host();
- if (host.startsWith("www.")) {
- host = host.substring(4);
- }
- return host;
+ private String getDomain(HttpUrl url) {
+ // String host = url.host();
+ // if (host.startsWith("www.")) {
+ // host = host.substring(4);
+ // }
+ // return host;
+ return url.topPrivateDomain();
}
@Override
diff --git a/common/src/main/java/ctbrec/sites/jasmin/LiveJasmin.java b/common/src/main/java/ctbrec/sites/jasmin/LiveJasmin.java
index cc53d667..1b3fd206 100644
--- a/common/src/main/java/ctbrec/sites/jasmin/LiveJasmin.java
+++ b/common/src/main/java/ctbrec/sites/jasmin/LiveJasmin.java
@@ -151,7 +151,7 @@ public class LiveJasmin extends AbstractSite {
@Override
public boolean credentialsAvailable() {
- return !Config.getInstance().getSettings().livejasminSession.isEmpty();
+ return !Config.getInstance().getSettings().livejasminUsername.isEmpty();
}
}
diff --git a/common/src/main/java/ctbrec/sites/jasmin/LiveJasminHttpClient.java b/common/src/main/java/ctbrec/sites/jasmin/LiveJasminHttpClient.java
index b979ee53..1d495599 100644
--- a/common/src/main/java/ctbrec/sites/jasmin/LiveJasminHttpClient.java
+++ b/common/src/main/java/ctbrec/sites/jasmin/LiveJasminHttpClient.java
@@ -1,7 +1,6 @@
package ctbrec.sites.jasmin;
import java.io.IOException;
-import java.util.Collections;
import java.util.NoSuchElementException;
import org.slf4j.Logger;
@@ -29,19 +28,6 @@ public class LiveJasminHttpClient extends HttpClient {
return true;
}
- // set session cookie, if session id is available
- if(!Config.getInstance().getSettings().livejasminSession.isEmpty()) {
- Cookie captchaCookie = new Cookie.Builder()
- .domain("livejasmin.com")
- .name("session")
- .value(Config.getInstance().getSettings().livejasminSession)
- .build();
- getCookieJar().saveFromResponse(HttpUrl.parse("https://livejasmin.com"), Collections.singletonList(captchaCookie));
- getCookieJar().saveFromResponse(HttpUrl.parse("https://www.livejasmin.com"), Collections.singletonList(captchaCookie));
- getCookieJar().saveFromResponse(HttpUrl.parse("https://m.livejasmin.com"), Collections.singletonList(captchaCookie));
- }
-
-
// loadMainPage(); // to get initial cookies
// Cookie captchaCookie = new Cookie.Builder()
// .domain("livejasmin.com")
@@ -152,10 +138,17 @@ public class LiveJasminHttpClient extends HttpClient {
.followRedirects(false)
.followSslRedirects(false)
.build();
- String url = LiveJasmin.BASE_URL + "/en/free/favourite/get-favourite-list";
+
+ // getCookieJar().getCookies().entrySet().forEach((e) -> {
+ // e.getValue().forEach(c -> {
+ // LOG.debug("LOGIN CHECK: Cookie {} {}={}", e.getKey(), c.name(), c.value());
+ // });
+ // });
+
+ String url = "https://m.livejasmin.com/en/member/favourite/get-favourite-list?ajax=1";
Request request = new Request.Builder()
.url(url)
- .addHeader("User-Agent", Config.getInstance().getSettings().httpUserAgent)
+ .addHeader("User-Agent", Config.getInstance().getSettings().httpUserAgentMobile)
.addHeader("Accept", "application/json, text/javascript, */*")
.addHeader("Accept-Language", "en")
.addHeader("Referer", LiveJasmin.BASE_URL)
@@ -166,13 +159,18 @@ public class LiveJasminHttpClient extends HttpClient {
if(response.isSuccessful()) {
return true;
} else {
+ // if(response.code() >= 300 && response.code() < 400) {
+ // for (String name : response.headers().names()) {
+ // LOG.debug("{}: {}", name, response.header(name));
+ // }
+ // }
return false;
}
}
}
public String getSessionId() {
- Cookie sessionCookie = getCookieJar().getCookie(HttpUrl.parse("https://www.livejasmin.com"), "session");
+ Cookie sessionCookie = getCookieJar().getCookie(HttpUrl.parse(LiveJasmin.BASE_URL), "session");
if(sessionCookie != null) {
return sessionCookie.value();
} else {
diff --git a/common/src/main/java/ctbrec/sites/jasmin/LiveJasminModel.java b/common/src/main/java/ctbrec/sites/jasmin/LiveJasminModel.java
index 24204da7..8722c6f4 100644
--- a/common/src/main/java/ctbrec/sites/jasmin/LiveJasminModel.java
+++ b/common/src/main/java/ctbrec/sites/jasmin/LiveJasminModel.java
@@ -280,6 +280,7 @@ public class LiveJasminModel extends AbstractModel {
// } else {
// return new LiveJasminWebSocketDownload(getSite().getHttpClient());
// }
- return new LiveJasminChunkedHttpDownload(getSite().getHttpClient());
+ //return new LiveJasminChunkedHttpDownload(getSite().getHttpClient());
+ return new LiveJasminWebSocketDownload(getSite().getHttpClient());
}
}
diff --git a/master/pom.xml b/master/pom.xml
index bc994b4a..34ff1e30 100644
--- a/master/pom.xml
+++ b/master/pom.xml
@@ -85,6 +85,11 @@
javafx-web
11
+
+ org.openjfx
+ javafx-media
+ 11
+
com.google.guava
guava