package ctbrec.ui.sites.flirt4free; import static ctbrec.io.HttpConstants.*; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.function.Predicate; import java.util.regex.Pattern; import java.util.stream.Collectors; import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ctbrec.Config; import ctbrec.Model; import ctbrec.io.HttpException; import ctbrec.sites.flirt4free.Flirt4Free; import ctbrec.sites.flirt4free.Flirt4FreeModel; import ctbrec.ui.tabs.PaginatedScheduledService; import javafx.concurrent.Task; import okhttp3.Request; import okhttp3.Response; public class Flirt4FreeUpdateService extends PaginatedScheduledService { private static final Logger LOG = LoggerFactory.getLogger(Flirt4FreeUpdateService.class); private static final int MODELS_PER_PAGE = 40; private String url; private Flirt4Free flirt4Free; private Predicate filter; public Flirt4FreeUpdateService(Flirt4Free flirt4Free, String url, Predicate filter) { this.flirt4Free = flirt4Free; this.url = url; this.filter = filter; } @Override protected Task> createTask() { return new Task>() { @Override public List call() throws IOException { LOG.debug("Fetching page {}", url); var request = new Request.Builder() .url(url) .header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent) .build(); try (var response = flirt4Free.getHttpClient().execute(request)) { if (response.isSuccessful()) { return parseResponse(response); } else { throw new HttpException(response.code(), response.message()); } } } }; } private List parseResponse(Response response) throws IOException { List models = new ArrayList<>(); var body = response.body().string(); var m = Pattern.compile("window\\.__homePageData__ = (\\{.*\\})", Pattern.DOTALL).matcher(body); if (m.find()) { var data = new JSONObject(m.group(1)); var modelData = data.getJSONArray("models"); LOG.debug("Found {} models", modelData.length()); for (var i = 0; i < modelData.length(); i++) { var modelJson = modelData.getJSONObject(i); try { Flirt4FreeModel model = parseModel(modelJson); models.add(model); } catch(Exception e) { LOG.warn("Couldn't parse model {}", modelJson); } } return models.stream() .filter(filter) .skip((page - 1) * (long)MODELS_PER_PAGE) .limit(MODELS_PER_PAGE) .collect(Collectors.toList()); } else { throw new IOException("Pattern didn't match model JSON data"); } } private Flirt4FreeModel parseModel(JSONObject modelData) { var name = modelData.getString("model_seo_name"); Flirt4FreeModel model = (Flirt4FreeModel) flirt4Free.createModel(name); model.setDisplayName(modelData.getString("display")); model.setDescription(modelData.getString("topic")); model.setUrl(Flirt4Free.BASE_URI + "/rooms/" + model.getName() + '/'); model.setNew(modelData.optString("is_new", "0").equals("1")); var videoHost = modelData.getString("video_host"); var modelId = modelData.getString("model_id"); model.setId(modelId); String streamUrl = "https://manifest.vscdns.com/manifest.m3u8.m3u8?key=nil&provider=level3&secure=true&host=" + videoHost + "&model_id=" + modelId; model.setStreamUrl(streamUrl); model.setPreview("https://live-screencaps.vscdns.com/"+ modelId +"-desktop.jpg"); model.setOnlineState(ctbrec.Model.State.ONLINE); model.setOnline(true); return model; } }