forked from j62/ctbrec
Fix Cam4 browser tabs
This commit is contained in:
parent
adf129a0c0
commit
f39b9ef13f
|
@ -1,15 +1,18 @@
|
||||||
package ctbrec.ui;
|
package ctbrec.ui;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import ctbrec.Model;
|
import ctbrec.Model;
|
||||||
import ctbrec.ui.sites.ConfigUI;
|
import ctbrec.ui.sites.ConfigUI;
|
||||||
import ctbrec.ui.tabs.TabProvider;
|
import ctbrec.ui.tabs.TabProvider;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
public interface SiteUI {
|
public interface SiteUI {
|
||||||
|
|
||||||
public TabProvider getTabProvider();
|
TabProvider getTabProvider();
|
||||||
public ConfigUI getConfigUI();
|
|
||||||
public boolean login() throws IOException;
|
ConfigUI getConfigUI();
|
||||||
public boolean play(Model model);
|
|
||||||
|
boolean login() throws IOException;
|
||||||
|
|
||||||
|
boolean play(Model model);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,11 +14,15 @@ import javafx.scene.input.KeyEvent;
|
||||||
import javafx.scene.layout.HBox;
|
import javafx.scene.layout.HBox;
|
||||||
|
|
||||||
public class Cam4FollowedTab extends ThumbOverviewTab implements FollowedTab {
|
public class Cam4FollowedTab extends ThumbOverviewTab implements FollowedTab {
|
||||||
private Label status;
|
private final Label status;
|
||||||
|
|
||||||
public Cam4FollowedTab(Cam4 cam4) {
|
public Cam4FollowedTab(Cam4 cam4) {
|
||||||
super("Followed", new Cam4FollowedUpdateService(cam4), cam4);
|
super("Followed", new Cam4FollowedUpdateService(cam4), cam4);
|
||||||
status = new Label("Logging in...");
|
if (cam4.credentialsAvailable()) {
|
||||||
|
status = new Label("Logging in...");
|
||||||
|
} else {
|
||||||
|
status = new Label("Credentials are missing in the settings");
|
||||||
|
}
|
||||||
grid.getChildren().add(status);
|
grid.getChildren().add(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,11 +40,11 @@ public class Cam4FollowedTab extends ThumbOverviewTab implements FollowedTab {
|
||||||
offline.setToggleGroup(group);
|
offline.setToggleGroup(group);
|
||||||
pagination.getChildren().add(online);
|
pagination.getChildren().add(online);
|
||||||
pagination.getChildren().add(offline);
|
pagination.getChildren().add(offline);
|
||||||
HBox.setMargin(online, new Insets(5,5,5,40));
|
HBox.setMargin(online, new Insets(5, 5, 5, 40));
|
||||||
HBox.setMargin(offline, new Insets(5,5,5,5));
|
HBox.setMargin(offline, new Insets(5, 5, 5, 5));
|
||||||
online.setSelected(true);
|
online.setSelected(true);
|
||||||
group.selectedToggleProperty().addListener(e -> {
|
group.selectedToggleProperty().addListener(e -> {
|
||||||
((Cam4FollowedUpdateService)updateService).setShowOnline(online.isSelected());
|
((Cam4FollowedUpdateService) updateService).setShowOnline(online.isSelected());
|
||||||
queue.clear();
|
queue.clear();
|
||||||
updateService.restart();
|
updateService.restart();
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,15 +1,5 @@
|
||||||
package ctbrec.ui.sites.cam4;
|
package ctbrec.ui.sites.cam4;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
|
|
||||||
import org.json.JSONObject;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import ctbrec.Model;
|
import ctbrec.Model;
|
||||||
import ctbrec.io.HttpException;
|
import ctbrec.io.HttpException;
|
||||||
import ctbrec.sites.cam4.Cam4;
|
import ctbrec.sites.cam4.Cam4;
|
||||||
|
@ -18,12 +8,22 @@ import ctbrec.ui.SiteUiFactory;
|
||||||
import ctbrec.ui.tabs.PaginatedScheduledService;
|
import ctbrec.ui.tabs.PaginatedScheduledService;
|
||||||
import javafx.concurrent.Task;
|
import javafx.concurrent.Task;
|
||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
public class Cam4FollowedUpdateService extends PaginatedScheduledService {
|
public class Cam4FollowedUpdateService extends PaginatedScheduledService {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(Cam4FollowedUpdateService.class);
|
private static final Logger LOG = LoggerFactory.getLogger(Cam4FollowedUpdateService.class);
|
||||||
|
|
||||||
private Cam4 site;
|
private final Cam4 site;
|
||||||
private boolean showOnline = true;
|
private boolean showOnline = true;
|
||||||
|
|
||||||
public Cam4FollowedUpdateService(Cam4 site) {
|
public Cam4FollowedUpdateService(Cam4 site) {
|
||||||
|
@ -39,7 +39,7 @@ public class Cam4FollowedUpdateService extends PaginatedScheduledService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Task<List<Model>> createTask() {
|
protected Task<List<Model>> createTask() {
|
||||||
return new Task<List<Model>>() {
|
return new Task<>() {
|
||||||
@Override
|
@Override
|
||||||
public List<Model> call() throws IOException {
|
public List<Model> call() throws IOException {
|
||||||
return loadModelList();
|
return loadModelList();
|
||||||
|
@ -48,6 +48,10 @@ public class Cam4FollowedUpdateService extends PaginatedScheduledService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Model> loadModelList() throws IOException {
|
private List<Model> loadModelList() throws IOException {
|
||||||
|
if (!site.credentialsAvailable()) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
// login first
|
// login first
|
||||||
SiteUiFactory.getUi(site).login();
|
SiteUiFactory.getUi(site).login();
|
||||||
String url = site.getBaseUrl() + "/directoryCams?directoryJson=true&online=" + showOnline + "&url=true&friends=true&favorites=true&resultsPerPage=90";
|
String url = site.getBaseUrl() + "/directoryCams?directoryJson=true&online=" + showOnline + "&url=true&friends=true&favorites=true&resultsPerPage=90";
|
||||||
|
|
|
@ -21,12 +21,13 @@ public class Cam4TabProvider extends AbstractTabProvider {
|
||||||
protected List<Tab> getSiteTabs(Scene scene) {
|
protected List<Tab> getSiteTabs(Scene scene) {
|
||||||
List<Tab> tabs = new ArrayList<>();
|
List<Tab> tabs = new ArrayList<>();
|
||||||
|
|
||||||
tabs.add(createTab("Female", site.getBaseUrl() + "/directoryResults?online=true&gender=female&orderBy=MOST_VIEWERS"));
|
tabs.add(createTab("Female", site.getBaseUrl() + "/directoryCams?directoryJson=true&online=true&url=true&orderBy=MOST_VIEWERS&gender=female"));
|
||||||
tabs.add(createTab("Male", site.getBaseUrl() + "/directoryResults?online=true&gender=male&orderBy=MOST_VIEWERS"));
|
tabs.add(createTab("Male", site.getBaseUrl() + "/directoryCams?directoryJson=true&online=true&url=true&orderBy=MOST_VIEWERS&gender=male"));
|
||||||
tabs.add(createTab("Trans", site.getBaseUrl() + "/directoryResults?online=true&gender=shemale&orderBy=MOST_VIEWERS"));
|
tabs.add(createTab("Trans", site.getBaseUrl() + "/directoryCams?directoryJson=true&online=true&url=true&orderBy=MOST_VIEWERS&gender=shemale"));
|
||||||
tabs.add(createTab("Couples", site.getBaseUrl() + "/directoryResults?online=true&broadcastType=male_group&broadcastType=female_group&broadcastType=male_female_group&orderBy=MOST_VIEWERS"));
|
tabs.add(createTab("Couples", site.getBaseUrl() + "/directoryCams?directoryJson=true&online=true&url=true&orderBy=MOST_VIEWERS&broadcastType=male_group&broadcastType=female_group&broadcastType=male_female_group"));
|
||||||
tabs.add(createTab("HD", site.getBaseUrl() + "/directoryResults?online=true&hd=true&orderBy=MOST_VIEWERS"));
|
tabs.add(createTab("HD", site.getBaseUrl() + "/directoryCams?directoryJson=true&online=true&url=true&orderBy=VIDEO_QUALITY&gender=female&broadcastType=female_group&broadcastType=solo&broadcastType=male_female_group&hd=true"));
|
||||||
tabs.add(createTab("New", site.getBaseUrl() + "/directoryResults?online=true&gender=female&orderBy=MOST_VIEWERS&newPerformer=true"));
|
tabs.add(createTab("Mobile", site.getBaseUrl() + "/directoryCams?directoryJson=true&online=true&url=true&orderBy=MOST_VIEWERS&gender=female&broadcastType=female_group&broadcastType=solo&broadcastType=male_female_group&source=mobile"));
|
||||||
|
tabs.add(createTab("New", site.getBaseUrl() + "/directoryCams?directoryJson=true&online=true&url=true&orderBy=MOST_VIEWERS&gender=female&broadcastType=female_group&broadcastType=solo&broadcastType=male_female_group&newPerformer=true"));
|
||||||
|
|
||||||
followed = new Cam4FollowedTab((Cam4) site);
|
followed = new Cam4FollowedTab((Cam4) site);
|
||||||
followed.setRecorder(recorder);
|
followed.setRecorder(recorder);
|
||||||
|
|
|
@ -1,7 +1,19 @@
|
||||||
package ctbrec.ui.sites.cam4;
|
package ctbrec.ui.sites.cam4;
|
||||||
|
|
||||||
import static ctbrec.Model.State.*;
|
import ctbrec.Config;
|
||||||
import static ctbrec.io.HttpConstants.*;
|
import ctbrec.Model;
|
||||||
|
import ctbrec.StringUtil;
|
||||||
|
import ctbrec.io.HttpException;
|
||||||
|
import ctbrec.sites.cam4.Cam4;
|
||||||
|
import ctbrec.sites.cam4.Cam4Model;
|
||||||
|
import ctbrec.ui.SiteUiFactory;
|
||||||
|
import ctbrec.ui.tabs.PaginatedScheduledService;
|
||||||
|
import javafx.concurrent.Task;
|
||||||
|
import okhttp3.Request;
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -11,29 +23,16 @@ import java.util.Locale;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
import org.json.JSONObject;
|
import static ctbrec.Model.State.ONLINE;
|
||||||
import org.jsoup.nodes.Element;
|
import static ctbrec.io.HttpConstants.ACCEPT_LANGUAGE;
|
||||||
import org.slf4j.Logger;
|
import static ctbrec.io.HttpConstants.USER_AGENT;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import ctbrec.Config;
|
|
||||||
import ctbrec.Model;
|
|
||||||
import ctbrec.StringUtil;
|
|
||||||
import ctbrec.io.HtmlParser;
|
|
||||||
import ctbrec.io.HttpException;
|
|
||||||
import ctbrec.sites.cam4.Cam4;
|
|
||||||
import ctbrec.sites.cam4.Cam4Model;
|
|
||||||
import ctbrec.ui.SiteUiFactory;
|
|
||||||
import ctbrec.ui.tabs.PaginatedScheduledService;
|
|
||||||
import javafx.concurrent.Task;
|
|
||||||
import okhttp3.Request;
|
|
||||||
|
|
||||||
public class Cam4UpdateService extends PaginatedScheduledService {
|
public class Cam4UpdateService extends PaginatedScheduledService {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(Cam4UpdateService.class);
|
private static final Logger LOG = LoggerFactory.getLogger(Cam4UpdateService.class);
|
||||||
private String url;
|
private String url;
|
||||||
private Cam4 site;
|
private final Cam4 site;
|
||||||
private boolean loginRequired;
|
private final boolean loginRequired;
|
||||||
|
|
||||||
public Cam4UpdateService(String url, boolean loginRequired, Cam4 site) {
|
public Cam4UpdateService(String url, boolean loginRequired, Cam4 site) {
|
||||||
this.site = site;
|
this.site = site;
|
||||||
|
@ -51,7 +50,7 @@ public class Cam4UpdateService extends PaginatedScheduledService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Task<List<Model>> createTask() {
|
protected Task<List<Model>> createTask() {
|
||||||
return new Task<List<Model>>() {
|
return new Task<>() {
|
||||||
@Override
|
@Override
|
||||||
public List<Model> call() throws IOException {
|
public List<Model> call() throws IOException {
|
||||||
if (loginRequired && StringUtil.isBlank(Config.getInstance().getSettings().cam4Username)) {
|
if (loginRequired && StringUtil.isBlank(Config.getInstance().getSettings().cam4Username)) {
|
||||||
|
@ -82,38 +81,20 @@ public class Cam4UpdateService extends PaginatedScheduledService {
|
||||||
|
|
||||||
private List<Model> parseModels(String body) {
|
private List<Model> parseModels(String body) {
|
||||||
var json = new JSONObject(body);
|
var json = new JSONObject(body);
|
||||||
var html = json.getString("html");
|
JSONArray users = json.getJSONArray("users");
|
||||||
var profilesBoxes = HtmlParser.getTags(html, "div[class~=profileDataBox]");
|
List<Model> models = new ArrayList<>(users.length());
|
||||||
List<Model> models = new ArrayList<>(profilesBoxes.size());
|
for (int i = 0; i < users.length(); i++) {
|
||||||
for (Element profileBox : profilesBoxes) {
|
JSONObject user = users.getJSONObject(i);
|
||||||
String boxHtml = profileBox.html();
|
Cam4Model model = site.createModel(user.getString("username"));
|
||||||
Element profileLink = HtmlParser.getTag(boxHtml, "a.profile-preview");
|
model.setPlaylistUrl(user.getString("hlsPreviewUrl"));
|
||||||
String path = profileLink.attr("href");
|
model.setPreview(user.getString("snapshotImageLink"));
|
||||||
var slug = path.substring(1);
|
model.setDescription(user.getString("statusMessage"));
|
||||||
Cam4Model model = site.createModel(slug);
|
|
||||||
String playlistUrl = profileLink.attr("data-hls-preview-url");
|
|
||||||
model.setDisplayName(HtmlParser.getText(boxHtml, "div.profileBoxTitle a").trim());
|
|
||||||
model.setPlaylistUrl(playlistUrl);
|
|
||||||
model.setPreview("https://snapshots.xcdnpro.com/thumbnails/" + model.getName() + "?s=" + System.currentTimeMillis());
|
|
||||||
model.setDescription(parseDesription(boxHtml));
|
|
||||||
model.setOnlineState(ONLINE);
|
model.setOnlineState(ONLINE);
|
||||||
if (boxHtml.contains("In private show")) {
|
|
||||||
model.setOnlineState(PRIVATE);
|
|
||||||
}
|
|
||||||
models.add(model);
|
models.add(model);
|
||||||
}
|
}
|
||||||
return models;
|
return models;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String parseDesription(String boxHtml) {
|
|
||||||
try {
|
|
||||||
return HtmlParser.getText(boxHtml, "div[class~=statusMsg2]");
|
|
||||||
} catch(Exception e) {
|
|
||||||
LOG.trace("Couldn't parse description for room");
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUrl(String url) {
|
public void setUrl(String url) {
|
||||||
this.url = url;
|
this.url = url;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,5 @@
|
||||||
package ctbrec.sites.cam4;
|
package ctbrec.sites.cam4;
|
||||||
|
|
||||||
import static ctbrec.io.HttpClient.*;
|
|
||||||
import static ctbrec.io.HttpConstants.*;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URLEncoder;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import ctbrec.Model;
|
import ctbrec.Model;
|
||||||
import ctbrec.StringUtil;
|
import ctbrec.StringUtil;
|
||||||
import ctbrec.io.HttpClient;
|
import ctbrec.io.HttpClient;
|
||||||
|
@ -20,6 +7,19 @@ import ctbrec.io.HttpException;
|
||||||
import ctbrec.sites.AbstractSite;
|
import ctbrec.sites.AbstractSite;
|
||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
import okhttp3.Response;
|
import okhttp3.Response;
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import static ctbrec.io.HttpClient.bodyToJsonArray;
|
||||||
|
import static ctbrec.io.HttpConstants.USER_AGENT;
|
||||||
|
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||||
|
|
||||||
public class Cam4 extends AbstractSite {
|
public class Cam4 extends AbstractSite {
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ public class Cam4 extends AbstractSite {
|
||||||
if (!credentialsAvailable()) {
|
if (!credentialsAvailable()) {
|
||||||
throw new IOException("Not logged in");
|
throw new IOException("Not logged in");
|
||||||
}
|
}
|
||||||
return ((Cam4HttpClient)getHttpClient()).getTokenBalance();
|
return ((Cam4HttpClient) getHttpClient()).getTokenBalance();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -114,13 +114,15 @@ public class Cam4 extends AbstractSite {
|
||||||
@Override
|
@Override
|
||||||
public List<Model> search(String q) throws IOException, InterruptedException {
|
public List<Model> search(String q) throws IOException, InterruptedException {
|
||||||
List<Model> result = new ArrayList<>();
|
List<Model> result = new ArrayList<>();
|
||||||
search(q, false, result);
|
if (credentialsAvailable()) {
|
||||||
search(q, true, result);
|
search(q, false, result);
|
||||||
|
search(q, true, result);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void search(String q, boolean offline, List<Model> models) throws IOException {
|
private void search(String q, boolean offline, List<Model> models) throws IOException {
|
||||||
String url = BASE_URI + "/usernameSearch?username=" + URLEncoder.encode(q, "utf-8");
|
String url = BASE_URI + "/usernameSearch?username=" + URLEncoder.encode(q, UTF_8);
|
||||||
if (offline) {
|
if (offline) {
|
||||||
url += "&offline=true";
|
url += "&offline=true";
|
||||||
}
|
}
|
||||||
|
@ -135,7 +137,7 @@ public class Cam4 extends AbstractSite {
|
||||||
for (int i = 0; i < results.length(); i++) {
|
for (int i = 0; i < results.length(); i++) {
|
||||||
JSONObject result = results.getJSONObject(i);
|
JSONObject result = results.getJSONObject(i);
|
||||||
Model model = createModel(result.getString("username"));
|
Model model = createModel(result.getString("username"));
|
||||||
String thumb = null;
|
String thumb;
|
||||||
if (result.has("thumbnailId")) {
|
if (result.has("thumbnailId")) {
|
||||||
thumb = "https://snapshots.xcdnpro.com/thumbnails/" + model.getName() + "?s=" + result.getString("thumbnailId");
|
thumb = "https://snapshots.xcdnpro.com/thumbnails/" + model.getName() + "?s=" + result.getString("thumbnailId");
|
||||||
} else {
|
} else {
|
||||||
|
@ -165,8 +167,8 @@ public class Cam4 extends AbstractSite {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Model createModelFromUrl(String url) {
|
public Model createModelFromUrl(String url) {
|
||||||
Matcher m = Pattern.compile("https?://(?:www\\.)?cam4(?:.*?).com/([^/]*?)/?").matcher(url);
|
Matcher m = Pattern.compile("https?://(?:www\\.)?cam4.*?.com/([^/]*?)/?").matcher(url);
|
||||||
if(m.matches()) {
|
if (m.matches()) {
|
||||||
String modelName = m.group(1);
|
String modelName = m.group(1);
|
||||||
return createModel(modelName);
|
return createModel(modelName);
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue