Add login dialog for Cam4
The login dialog uses a WebView to load the login form from cam4.com Username and password get filled in by ctbrec, the user has to solve the captcha. Afterwards all cookies (especially the session cookie) are extracted from the webview and transfered to the OkHttp client, so that it can be used for further requests.
This commit is contained in:
parent
64beb44316
commit
43cb005fcd
|
@ -24,6 +24,8 @@ public class Settings {
|
|||
public String password = ""; // chaturbate password TODO maybe rename this onetime
|
||||
public String mfcUsername = "";
|
||||
public String mfcPassword = "";
|
||||
public String cam4Username;
|
||||
public String cam4Password;
|
||||
public String lastDownloadDir = "";
|
||||
|
||||
public List<Model> models = new ArrayList<Model>();
|
||||
|
|
|
@ -62,17 +62,13 @@ public class Cam4 extends AbstractSite {
|
|||
|
||||
@Override
|
||||
public void login() throws IOException {
|
||||
getHttpClient().login();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpClient getHttpClient() {
|
||||
if(httpClient == null) {
|
||||
httpClient = new HttpClient() {
|
||||
@Override
|
||||
public boolean login() throws IOException {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
httpClient = new Cam4HttpClient();
|
||||
}
|
||||
return httpClient;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
package ctbrec.sites.cam4;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.HttpCookie;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import ctbrec.io.HttpClient;
|
||||
import okhttp3.Cookie;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
|
||||
public class Cam4HttpClient extends HttpClient {
|
||||
|
||||
@Override
|
||||
public boolean login() throws IOException {
|
||||
// login with javafx WebView
|
||||
Cam4LoginDialog loginDialog = new Cam4LoginDialog();
|
||||
|
||||
// transfer cookies from WebView to OkHttp cookie jar
|
||||
transferCookies(loginDialog);
|
||||
|
||||
return checkLoginSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* check, if the login worked by requesting unchecked mail
|
||||
* @throws IOException
|
||||
*/
|
||||
private boolean checkLoginSuccess() throws IOException {
|
||||
String mailUrl = "https://www.cam4.de.com/mail/unreadThreads";
|
||||
Request req = new Request.Builder().url(mailUrl).build();
|
||||
Response response = execute(req);
|
||||
if(response.isSuccessful()) {
|
||||
JSONObject json = new JSONObject(response.body().string());
|
||||
return json.has("status") && Objects.equals("success", json.getString("status"));
|
||||
} else {
|
||||
response.close();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void transferCookies(Cam4LoginDialog 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);
|
||||
}
|
||||
cookieJar.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);
|
||||
}
|
||||
cookieJar.saveFromResponse(origUrl, cookies);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
package ctbrec.sites.cam4;
|
||||
|
||||
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 javafx.concurrent.Worker.State;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.ProgressIndicator;
|
||||
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<HttpCookie> cookies = null;
|
||||
private String url;
|
||||
private Region veil;
|
||||
private ProgressIndicator p;
|
||||
|
||||
public Cam4LoginDialog() {
|
||||
Stage stage = new Stage();
|
||||
stage.setTitle("Cam4 Login");
|
||||
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)");
|
||||
//veil.setPrefSize(240, 160);
|
||||
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.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) -> {
|
||||
System.out.println(newState);
|
||||
if (newState == State.SUCCEEDED) {
|
||||
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')");
|
||||
veil.setVisible(false);
|
||||
p.setVisible(false);
|
||||
} else if (newState == State.CANCELLED || newState == State.FAILED) {
|
||||
veil.setVisible(false);
|
||||
p.setVisible(false);
|
||||
}
|
||||
});
|
||||
webEngine.load(URL);
|
||||
return browser;
|
||||
}
|
||||
|
||||
public List<HttpCookie> getCookies() {
|
||||
return cookies;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@ import java.util.Iterator;
|
|||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -50,7 +51,11 @@ public class CookieJarImpl implements CookieJar {
|
|||
public List<Cookie> loadForRequest(HttpUrl url) {
|
||||
String host = getHost(url);
|
||||
List<Cookie> cookies = cookieStore.get(host);
|
||||
LOG.debug("Cookies for {}: {}", url.host(), cookies);
|
||||
LOG.debug("Cookies for {}", url);
|
||||
Optional.ofNullable(cookies).ifPresent(cookiez -> cookiez.forEach(c -> {
|
||||
LOG.debug(" {} expires on:{}", c, c.expiresAt());
|
||||
}));
|
||||
//LOG.debug("Cookies for {}: {}", url.host(), cookies);
|
||||
return cookies != null ? cookies : new ArrayList<Cookie>();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue