Implement follow/unfollow for Flirt4Free
This commit is contained in:
parent
8f5c7ac9c4
commit
204eb99b29
|
@ -495,7 +495,7 @@ public class ThumbOverviewTab extends Tab implements TabSelectionListener {
|
||||||
LOG.error("An error occured while sending tip", ex);
|
LOG.error("An error occured while sending tip", ex);
|
||||||
showError("Couldn't send tip", "An error occured while sending tip:", ex);
|
showError("Couldn't send tip", "An error occured while sending tip:", ex);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
showError("Couldn't send tip", "You entered an invalid amount of tokens", null);
|
showError("Couldn't send tip", "You entered an invalid amount of tokens", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package ctbrec.ui.sites.flirt4free;
|
||||||
|
|
||||||
|
import ctbrec.sites.flirt4free.Flirt4Free;
|
||||||
|
import ctbrec.ui.FollowedTab;
|
||||||
|
import ctbrec.ui.ThumbOverviewTab;
|
||||||
|
import javafx.scene.Scene;
|
||||||
|
import javafx.scene.input.KeyCode;
|
||||||
|
import javafx.scene.input.KeyEvent;
|
||||||
|
|
||||||
|
public class Flirt4FreeFavoritesTab extends ThumbOverviewTab implements FollowedTab {
|
||||||
|
|
||||||
|
public Flirt4FreeFavoritesTab(Flirt4Free flirt4free) {
|
||||||
|
super("Favorites", new Flirt4FreeFavoritesUpdateService(flirt4free), flirt4free);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScene(Scene scene) {
|
||||||
|
scene.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
|
||||||
|
if(this.isSelected()) {
|
||||||
|
if(event.getCode() == KeyCode.DELETE) {
|
||||||
|
follow(selectedThumbCells, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
package ctbrec.ui.sites.flirt4free;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
|
import org.jsoup.nodes.Element;
|
||||||
|
import org.jsoup.select.Elements;
|
||||||
|
|
||||||
|
import ctbrec.Config;
|
||||||
|
import ctbrec.Model;
|
||||||
|
import ctbrec.io.HtmlParser;
|
||||||
|
import ctbrec.io.HttpException;
|
||||||
|
import ctbrec.sites.flirt4free.Flirt4Free;
|
||||||
|
import ctbrec.sites.flirt4free.Flirt4FreeModel;
|
||||||
|
import ctbrec.ui.PaginatedScheduledService;
|
||||||
|
import ctbrec.ui.SiteUiFactory;
|
||||||
|
import javafx.concurrent.Task;
|
||||||
|
import okhttp3.Request;
|
||||||
|
import okhttp3.Response;
|
||||||
|
|
||||||
|
public class Flirt4FreeFavoritesUpdateService extends PaginatedScheduledService {
|
||||||
|
private Flirt4Free flirt4free;
|
||||||
|
|
||||||
|
public Flirt4FreeFavoritesUpdateService(Flirt4Free flirt4free) {
|
||||||
|
this.flirt4free = flirt4free;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Task<List<Model>> createTask() {
|
||||||
|
return new Task<List<Model>>() {
|
||||||
|
@Override
|
||||||
|
public List<Model> call() throws IOException {
|
||||||
|
List<Model> models = new ArrayList<>();
|
||||||
|
String url = flirt4free.getBaseUrl() + "/my-account/secure/favorites.php?a=models&sort=online&pg=" + page;
|
||||||
|
SiteUiFactory.getUi(flirt4free).login();
|
||||||
|
Request request = new Request.Builder()
|
||||||
|
.url(url)
|
||||||
|
.header("Accept", "*/*")
|
||||||
|
.header("Accept-Language", "en-US,en;q=0.5")
|
||||||
|
.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 (ExecutionException | InterruptedException e) {}
|
||||||
|
models.add(model);
|
||||||
|
}
|
||||||
|
return models;
|
||||||
|
} else {
|
||||||
|
throw new HttpException(response.code(), response.message());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,9 +13,12 @@ import javafx.util.Duration;
|
||||||
public class Flirt4FreeTabProvider extends TabProvider {
|
public class Flirt4FreeTabProvider extends TabProvider {
|
||||||
|
|
||||||
private Flirt4Free flirt4Free;
|
private Flirt4Free flirt4Free;
|
||||||
|
private ThumbOverviewTab followedTab;
|
||||||
|
|
||||||
public Flirt4FreeTabProvider(Flirt4Free flirt4Free) {
|
public Flirt4FreeTabProvider(Flirt4Free flirt4Free) {
|
||||||
this.flirt4Free = flirt4Free;
|
this.flirt4Free = flirt4Free;
|
||||||
|
followedTab = new Flirt4FreeFavoritesTab(flirt4Free);
|
||||||
|
followedTab.setRecorder(flirt4Free.getRecorder());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -24,12 +27,13 @@ public class Flirt4FreeTabProvider extends TabProvider {
|
||||||
tabs.add(createTab("Girls", flirt4Free.getBaseUrl() + "/live/girls/"));
|
tabs.add(createTab("Girls", flirt4Free.getBaseUrl() + "/live/girls/"));
|
||||||
tabs.add(createTab("Boys", flirt4Free.getBaseUrl() + "/live/guys/"));
|
tabs.add(createTab("Boys", flirt4Free.getBaseUrl() + "/live/guys/"));
|
||||||
tabs.add(createTab("Trans", flirt4Free.getBaseUrl() + "/live/trans/"));
|
tabs.add(createTab("Trans", flirt4Free.getBaseUrl() + "/live/trans/"));
|
||||||
|
tabs.add(followedTab);
|
||||||
return tabs;
|
return tabs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tab getFollowedTab() {
|
public Tab getFollowedTab() {
|
||||||
return null;
|
return followedTab;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ThumbOverviewTab createTab(String title, String url) {
|
private ThumbOverviewTab createTab(String title, String url) {
|
||||||
|
|
|
@ -9,8 +9,6 @@ import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.jsoup.nodes.Element;
|
import org.jsoup.nodes.Element;
|
||||||
import org.jsoup.select.Elements;
|
import org.jsoup.select.Elements;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import ctbrec.Config;
|
import ctbrec.Config;
|
||||||
import ctbrec.Model;
|
import ctbrec.Model;
|
||||||
|
@ -23,7 +21,6 @@ import okhttp3.Response;
|
||||||
|
|
||||||
public class Flirt4Free extends AbstractSite {
|
public class Flirt4Free extends AbstractSite {
|
||||||
|
|
||||||
private static final transient Logger LOG = LoggerFactory.getLogger(Flirt4Free.class);
|
|
||||||
public static final String BASE_URI = "https://www.flirt4free.com";
|
public static final String BASE_URI = "https://www.flirt4free.com";
|
||||||
private HttpClient httpClient;
|
private HttpClient httpClient;
|
||||||
|
|
||||||
|
@ -106,12 +103,12 @@ public class Flirt4Free extends AbstractSite {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsTips() {
|
public boolean supportsTips() {
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsFollow() {
|
public boolean supportsFollow() {
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -8,6 +8,8 @@ import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -47,6 +49,9 @@ public class Flirt4FreeModel extends AbstractModel {
|
||||||
int[] resolution = new int[2];
|
int[] resolution = new int[2];
|
||||||
private Object monitor = new Object();
|
private Object monitor = new Object();
|
||||||
private boolean online = false;
|
private boolean online = false;
|
||||||
|
private boolean isInteractiveShow = false;
|
||||||
|
private String userIdt = "";
|
||||||
|
private String userIp = "0.0.0.0";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isOnline(boolean ignoreCache) throws IOException, ExecutionException, InterruptedException {
|
public boolean isOnline(boolean ignoreCache) throws IOException, ExecutionException, InterruptedException {
|
||||||
|
@ -63,6 +68,7 @@ public class Flirt4FreeModel extends AbstractModel {
|
||||||
try(Response response = getSite().getHttpClient().execute(request)) {
|
try(Response response = getSite().getHttpClient().execute(request)) {
|
||||||
if(response.isSuccessful()) {
|
if(response.isSuccessful()) {
|
||||||
JSONObject json = new JSONObject(response.body().string());
|
JSONObject json = new JSONObject(response.body().string());
|
||||||
|
//LOG.debug("check model status: {}", json.toString(2));
|
||||||
online = Objects.equals(json.optString("status"), "online");
|
online = Objects.equals(json.optString("status"), "online");
|
||||||
id = json.getString("model_id");
|
id = json.getString("model_id");
|
||||||
if(online) {
|
if(online) {
|
||||||
|
@ -96,6 +102,7 @@ public class Flirt4FreeModel extends AbstractModel {
|
||||||
if(response.isSuccessful()) {
|
if(response.isSuccessful()) {
|
||||||
JSONObject json = new JSONObject(response.body().string());
|
JSONObject json = new JSONObject(response.body().string());
|
||||||
if(json.optString("status").equals("success")) {
|
if(json.optString("status").equals("success")) {
|
||||||
|
//LOG.debug("chat-room-interface {}", json.toString(2));
|
||||||
JSONObject config = json.getJSONObject("config");
|
JSONObject config = json.getJSONObject("config");
|
||||||
JSONObject performer = config.getJSONObject("performer");
|
JSONObject performer = config.getJSONObject("performer");
|
||||||
setName(performer.optString("name_seo", "n/a"));
|
setName(performer.optString("name_seo", "n/a"));
|
||||||
|
@ -105,6 +112,8 @@ public class Flirt4FreeModel extends AbstractModel {
|
||||||
chatHost = room.getString("host");
|
chatHost = room.getString("host");
|
||||||
chatPort = room.getString("port_to_be");
|
chatPort = room.getString("port_to_be");
|
||||||
chatToken = json.getString("token_enc");
|
chatToken = json.getString("token_enc");
|
||||||
|
JSONObject user = config.getJSONObject("user");
|
||||||
|
userIp = user.getString("ip");
|
||||||
} else {
|
} else {
|
||||||
LOG.trace("Loading model info failed. Assuming model {} is offline", getName());
|
LOG.trace("Loading model info failed. Assuming model {} is offline", getName());
|
||||||
online = false;
|
online = false;
|
||||||
|
@ -193,10 +202,20 @@ public class Flirt4FreeModel extends AbstractModel {
|
||||||
public void onMessage(WebSocket webSocket, String text) {
|
public void onMessage(WebSocket webSocket, String text) {
|
||||||
LOG.trace("Chat wbesocket for {}: {}", getName(), text);
|
LOG.trace("Chat wbesocket for {}: {}", getName(), text);
|
||||||
JSONObject json = new JSONObject(text);
|
JSONObject json = new JSONObject(text);
|
||||||
|
//LOG.debug("WS {}", text);
|
||||||
if (json.optString("command").equals("8011")) {
|
if (json.optString("command").equals("8011")) {
|
||||||
JSONObject data = json.getJSONObject("data");
|
JSONObject data = json.getJSONObject("data");
|
||||||
streamHost = data.getString("stream_host");
|
streamHost = data.getString("stream_host"); // TODO look, if the stream_host is equal to the one encoded in base64 in some of the ajax requests (parameters)
|
||||||
online = true;
|
online = true;
|
||||||
|
isInteractiveShow = data.optString("devices").equals("1");
|
||||||
|
if(data.optString("room_state").equals("P")) {
|
||||||
|
onlineState = Model.State.PRIVATE;
|
||||||
|
online = false;
|
||||||
|
}
|
||||||
|
if(data.optString("room_state").equals("0") && data.optString("login_group_id").equals("14")) {
|
||||||
|
onlineState = Model.State.GROUP;
|
||||||
|
online = false;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
resolution[0] = Integer.parseInt(data.getString("stream_width"));
|
resolution[0] = Integer.parseInt(data.getString("stream_width"));
|
||||||
resolution[1] = Integer.parseInt(data.getString("stream_height"));
|
resolution[1] = Integer.parseInt(data.getString("stream_height"));
|
||||||
|
@ -239,6 +258,82 @@ public class Flirt4FreeModel extends AbstractModel {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void receiveTip(Double tokens) throws IOException {
|
public void receiveTip(Double tokens) throws IOException {
|
||||||
|
// if(tokens < 50 || tokens > 750000) {
|
||||||
|
// throw new RuntimeException("Tip amount has to be between 50 and 750000");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// make sure we are logged in and all necessary model data is available
|
||||||
|
getSite().login();
|
||||||
|
try {
|
||||||
|
loadStreamUrl();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new IOException("Couldn't send tip", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// send the tip
|
||||||
|
int giftId = isInteractiveShow ? 775 : 171;
|
||||||
|
int amount = tokens.intValue();
|
||||||
|
LOG.debug("Sending tip of {} to {}", amount, getName());
|
||||||
|
String url = "https://ws.vs3.com/rooms/send-tip.php?" +
|
||||||
|
"gift_id=" + giftId +
|
||||||
|
"&num_credits=" + amount +
|
||||||
|
"&userId=" + getUserIdt() +
|
||||||
|
"&username=" + Config.getInstance().getSettings().flirt4freeUsername +
|
||||||
|
"&userIP=" + userIp +
|
||||||
|
"&anonymous=N&response_type=json" +
|
||||||
|
"&t=" + System.currentTimeMillis();
|
||||||
|
LOG.debug("Trying to send tip: {}", url);
|
||||||
|
Request req = new Request.Builder()
|
||||||
|
.url(url)
|
||||||
|
.header("Accept", "*/*")
|
||||||
|
.header("Accept-Language", "en-US,en;q=0.5")
|
||||||
|
.header("Referer", getUrl())
|
||||||
|
.header("User-Agent", Config.getInstance().getSettings().httpUserAgent)
|
||||||
|
.header("Referer", getUrl())
|
||||||
|
.header("X-Requested-With", "XMLHttpRequest")
|
||||||
|
.build();
|
||||||
|
try (Response response = getSite().getHttpClient().execute(req)) {
|
||||||
|
if(response.isSuccessful()) {
|
||||||
|
JSONObject json = new JSONObject(response.body().string());
|
||||||
|
if(json.optInt("success") != 1) {
|
||||||
|
String msg = json.optString("message");
|
||||||
|
if(json.has("error_message")) {
|
||||||
|
msg = json.getString("error_message");
|
||||||
|
}
|
||||||
|
LOG.error("Sending tip failed: {}", msg);
|
||||||
|
LOG.debug("Response: {}", json.toString(2));
|
||||||
|
throw new IOException(msg);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new HttpException(response.code(), response.message());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getUserIdt() throws IOException {
|
||||||
|
if(userIdt.isEmpty()) {
|
||||||
|
Request req = new Request.Builder()
|
||||||
|
.url(getUrl())
|
||||||
|
.header("Accept", "*/*")
|
||||||
|
.header("Accept-Language", "en-US,en;q=0.5")
|
||||||
|
.header("Referer", getUrl())
|
||||||
|
.header("User-Agent", Config.getInstance().getSettings().httpUserAgent)
|
||||||
|
.build();
|
||||||
|
try (Response response = getSite().getHttpClient().execute(req)) {
|
||||||
|
if(response.isSuccessful()) {
|
||||||
|
String body = response.body().string();
|
||||||
|
Matcher m = Pattern.compile("idt\\s*:\\s*'(.*?)',").matcher(body);
|
||||||
|
if(m.find()) {
|
||||||
|
userIdt = m.group(1);
|
||||||
|
} else {
|
||||||
|
throw new IOException("userIdt not found on HTML page");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new HttpException(response.code(), response.message());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return userIdt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -262,12 +357,44 @@ public class Flirt4FreeModel extends AbstractModel {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean follow() throws IOException {
|
public boolean follow() throws IOException {
|
||||||
return false;
|
return changeFavoriteStatus(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean unfollow() throws IOException {
|
public boolean unfollow() throws IOException {
|
||||||
return false;
|
try {
|
||||||
|
isOnline(true);
|
||||||
|
} catch (ExecutionException | InterruptedException e) {
|
||||||
|
throw new IOException("Couldn't rectrieve model id", e);
|
||||||
|
}
|
||||||
|
return changeFavoriteStatus(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean changeFavoriteStatus(boolean add) throws IOException {
|
||||||
|
getSite().login();
|
||||||
|
loadModelInfo();
|
||||||
|
String url = getSite().getBaseUrl() + "/external.php?a=" +
|
||||||
|
(add ? "add_favorite" : "delete_favorite") +
|
||||||
|
"&id=" + id +
|
||||||
|
"&name=" + getDisplayName() +
|
||||||
|
"&t=" + System.currentTimeMillis();
|
||||||
|
LOG.debug("Sending follow/unfollow request: {}", url);
|
||||||
|
Request req = new Request.Builder()
|
||||||
|
.url(url)
|
||||||
|
.header("Accept", "*/*")
|
||||||
|
.header("Accept-Language", "en-US,en;q=0.5")
|
||||||
|
.header("Referer", getUrl())
|
||||||
|
.header("User-Agent", Config.getInstance().getSettings().httpUserAgent)
|
||||||
|
.build();
|
||||||
|
try (Response response = getSite().getHttpClient().execute(req)) {
|
||||||
|
if(response.isSuccessful()) {
|
||||||
|
String body = response.body().string();
|
||||||
|
LOG.debug("Follow/Unfollow response: {}", body);
|
||||||
|
return Objects.equals(body, "1");
|
||||||
|
} else {
|
||||||
|
throw new HttpException(response.code(), response.message());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setId(String id) {
|
public void setId(String id) {
|
||||||
|
|
Loading…
Reference in New Issue