Code cleanup

This commit is contained in:
0xb00bface 2022-10-15 20:04:55 +02:00
parent 856743c00a
commit 8b31df73c5
2 changed files with 87 additions and 107 deletions

View File

@ -1,14 +1,6 @@
package ctbrec.ui.sites.chaturbate; package ctbrec.ui.sites.chaturbate;
import java.io.IOException; import ctbrec.Config;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ctbrec.Model; import ctbrec.Model;
import ctbrec.sites.chaturbate.Chaturbate; import ctbrec.sites.chaturbate.Chaturbate;
import ctbrec.sites.chaturbate.ChaturbateModelParser; import ctbrec.sites.chaturbate.ChaturbateModelParser;
@ -16,13 +8,23 @@ 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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import static ctbrec.io.HttpConstants.*;
public class ChaturbateUpdateService extends PaginatedScheduledService { public class ChaturbateUpdateService extends PaginatedScheduledService {
private static final Logger LOG = LoggerFactory.getLogger(ChaturbateUpdateService.class); private static final Logger LOG = LoggerFactory.getLogger(ChaturbateUpdateService.class);
private String url; private String url;
private boolean loginRequired; private final boolean loginRequired;
private Chaturbate chaturbate; private final Chaturbate chaturbate;
public ChaturbateUpdateService(String url, boolean loginRequired, Chaturbate chaturbate) { public ChaturbateUpdateService(String url, boolean loginRequired, Chaturbate chaturbate) {
this.url = url; this.url = url;
@ -40,18 +42,22 @@ public class ChaturbateUpdateService 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 && !chaturbate.credentialsAvailable()) { if (loginRequired && !chaturbate.credentialsAvailable()) {
return Collections.emptyList(); return Collections.emptyList();
} else { } else {
String pageUrl = ChaturbateUpdateService.this.url + "?page="+page+"&keywords=&_=" + System.currentTimeMillis(); String pageUrl = ChaturbateUpdateService.this.url + "?page=" + page + "&keywords=&_=" + System.currentTimeMillis();
LOG.debug("Fetching page {}", pageUrl); LOG.debug("Fetching page {}", pageUrl);
if(loginRequired) { if (loginRequired) {
SiteUiFactory.getUi(chaturbate).login(); SiteUiFactory.getUi(chaturbate).login();
} }
var request = new Request.Builder().url(pageUrl).build(); var request = new Request.Builder()
.url(pageUrl)
.header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent)
.header(ACCEPT, MIMETYPE_TEXT_HTML)
.build();
try (var response = chaturbate.getHttpClient().execute(request)) { try (var response = chaturbate.getHttpClient().execute(request)) {
if (response.isSuccessful()) { if (response.isSuccessful()) {
List<Model> models = ChaturbateModelParser.parseModels(chaturbate, response.body().string()); List<Model> models = ChaturbateModelParser.parseModels(chaturbate, response.body().string());

View File

@ -1,38 +1,11 @@
package ctbrec.sites.chaturbate; package ctbrec.sites.chaturbate;
import static ctbrec.Model.State.*; import com.iheartradio.m3u8.*;
import static ctbrec.io.HttpConstants.*;
import static java.nio.charset.StandardCharsets.*;
import java.io.ByteArrayInputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.iheartradio.m3u8.Encoding;
import com.iheartradio.m3u8.Format;
import com.iheartradio.m3u8.ParseException;
import com.iheartradio.m3u8.ParsingMode;
import com.iheartradio.m3u8.PlaylistException;
import com.iheartradio.m3u8.PlaylistParser;
import com.iheartradio.m3u8.data.MasterPlaylist; import com.iheartradio.m3u8.data.MasterPlaylist;
import com.iheartradio.m3u8.data.Playlist; import com.iheartradio.m3u8.data.Playlist;
import com.iheartradio.m3u8.data.PlaylistData; import com.iheartradio.m3u8.data.PlaylistData;
import com.squareup.moshi.JsonAdapter; import com.squareup.moshi.JsonAdapter;
import com.squareup.moshi.Moshi; import com.squareup.moshi.Moshi;
import ctbrec.AbstractModel; import ctbrec.AbstractModel;
import ctbrec.Config; import ctbrec.Config;
import ctbrec.io.HttpException; import ctbrec.io.HttpException;
@ -41,6 +14,22 @@ import okhttp3.FormBody;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.RequestBody; import okhttp3.RequestBody;
import okhttp3.Response; import okhttp3.Response;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayInputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.time.Duration;
import java.time.Instant;
import java.util.*;
import java.util.concurrent.ExecutionException;
import static ctbrec.Model.State.*;
import static ctbrec.io.HttpConstants.*;
import static java.nio.charset.StandardCharsets.UTF_8;
public class ChaturbateModel extends AbstractModel { // NOSONAR public class ChaturbateModel extends AbstractModel { // NOSONAR
@ -50,9 +39,11 @@ public class ChaturbateModel extends AbstractModel { // NOSONAR
private transient StreamInfo streamInfo; private transient StreamInfo streamInfo;
private transient Instant lastStreamInfoRequest = Instant.EPOCH; private transient Instant lastStreamInfoRequest = Instant.EPOCH;
/** /**
* This constructor exists only for deserialization. Please don't call it directly * This constructor exists only for deserialization. Please don't call it directly
*/ */
@SuppressWarnings("unused")
public ChaturbateModel() { public ChaturbateModel() {
} }
@ -76,13 +67,13 @@ public class ChaturbateModel extends AbstractModel { // NOSONAR
@Override @Override
public int[] getStreamResolution(boolean failFast) throws ExecutionException { public int[] getStreamResolution(boolean failFast) throws ExecutionException {
if(failFast) { if (failFast) {
return resolution; return resolution;
} }
try { try {
resolution = getResolution(); resolution = getResolution();
} catch(Exception e) { } catch (Exception e) {
throw new ExecutionException(e); throw new ExecutionException(e);
} }
return resolution; return resolution;
@ -115,27 +106,15 @@ public class ChaturbateModel extends AbstractModel { // NOSONAR
private void setOnlineStateByRoomStatus(String roomStatus) { private void setOnlineStateByRoomStatus(String roomStatus) {
if (roomStatus != null) { if (roomStatus != null) {
switch (roomStatus) { switch (roomStatus) {
case PUBLIC: case PUBLIC, "Unknown" -> onlineState = ONLINE;
case "Unknown": case "offline" -> onlineState = OFFLINE;
onlineState = ONLINE; case "private", "hidden", "password protected" -> onlineState = PRIVATE;
break; case "away" -> onlineState = AWAY;
case "offline": case "group" -> onlineState = State.GROUP;
onlineState = OFFLINE; default -> {
break; LOG.debug("Unknown show type {}", roomStatus);
case "private": onlineState = State.UNKNOWN;
case "hidden": }
case "password protected":
onlineState = PRIVATE;
break;
case "away":
onlineState = AWAY;
break;
case "group":
onlineState = State.GROUP;
break;
default:
LOG.debug("Unknown show type {}", roomStatus);
onlineState = State.UNKNOWN;
} }
} }
} }
@ -144,14 +123,14 @@ public class ChaturbateModel extends AbstractModel { // NOSONAR
public void receiveTip(Double tokens) throws IOException { public void receiveTip(Double tokens) throws IOException {
if (!Objects.equals(System.getenv("CTBREC_DEV"), "1")) { if (!Objects.equals(System.getenv("CTBREC_DEV"), "1")) {
RequestBody body = new FormBody.Builder() RequestBody body = new FormBody.Builder()
.add("csrfmiddlewaretoken", ((ChaturbateHttpClient)getSite().getHttpClient()).getToken()) .add("csrfmiddlewaretoken", ((ChaturbateHttpClient) getSite().getHttpClient()).getToken())
.add("tip_amount", Integer.toString(tokens.intValue())) .add("tip_amount", Integer.toString(tokens.intValue()))
.add("tip_room_type", PUBLIC) .add("tip_room_type", PUBLIC)
.build(); .build();
Request req = new Request.Builder() Request req = new Request.Builder()
.url("https://chaturbate.com/tipping/send_tip/"+getName()+"/") .url("https://chaturbate.com/tipping/send_tip/" + getName() + "/")
.post(body) .post(body)
.header(REFERER, "https://chaturbate.com/"+getName()+"/") .header(REFERER, "https://chaturbate.com/" + getName() + "/")
.header(X_REQUESTED_WITH, XML_HTTP_REQUEST) .header(X_REQUESTED_WITH, XML_HTTP_REQUEST)
.header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent) .header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent)
.build(); .build();
@ -165,31 +144,26 @@ public class ChaturbateModel extends AbstractModel { // NOSONAR
@Override @Override
public List<StreamSource> getStreamSources() throws IOException, ExecutionException, ParseException, PlaylistException { public List<StreamSource> getStreamSources() throws IOException, ExecutionException, ParseException, PlaylistException {
try { streamInfo = loadStreamInfo();
streamInfo = loadStreamInfo(); MasterPlaylist masterPlaylist = getMasterPlaylist();
MasterPlaylist masterPlaylist = getMasterPlaylist(); List<StreamSource> sources = new ArrayList<>();
List<StreamSource> sources = new ArrayList<>(); for (PlaylistData playlist : masterPlaylist.getPlaylists()) {
for (PlaylistData playlist : masterPlaylist.getPlaylists()) { if (playlist.hasStreamInfo()) {
if (playlist.hasStreamInfo()) { StreamSource src = new StreamSource();
StreamSource src = new StreamSource(); src.bandwidth = playlist.getStreamInfo().getBandwidth();
src.bandwidth = playlist.getStreamInfo().getBandwidth(); src.height = playlist.getStreamInfo().getResolution().height;
src.height = playlist.getStreamInfo().getResolution().height; String masterUrl = streamInfo.url;
String masterUrl = streamInfo.url; String baseUrl = masterUrl.substring(0, masterUrl.lastIndexOf('/') + 1);
String baseUrl = masterUrl.substring(0, masterUrl.lastIndexOf('/') + 1); String segmentUri = baseUrl + playlist.getUri();
String segmentUri = baseUrl + playlist.getUri(); src.mediaPlaylistUrl = segmentUri;
src.mediaPlaylistUrl = segmentUri; if (src.mediaPlaylistUrl.contains("?")) {
if(src.mediaPlaylistUrl.contains("?")) { src.mediaPlaylistUrl = src.mediaPlaylistUrl.substring(0, src.mediaPlaylistUrl.lastIndexOf('?'));
src.mediaPlaylistUrl = src.mediaPlaylistUrl.substring(0, src.mediaPlaylistUrl.lastIndexOf('?'));
}
LOG.trace("Media playlist {}", src.mediaPlaylistUrl);
sources.add(src);
} }
LOG.trace("Media playlist {}", src.mediaPlaylistUrl);
sources.add(src);
} }
return sources;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new ExecutionException(e);
} }
return sources;
} }
@Override @Override
@ -203,15 +177,15 @@ public class ChaturbateModel extends AbstractModel { // NOSONAR
} }
private boolean follow(boolean follow) throws IOException { private boolean follow(boolean follow) throws IOException {
// do an initial request to get cookies
Request req = new Request.Builder() Request req = new Request.Builder()
.url(getUrl()) .url(getUrl())
.header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent) .header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent)
.build(); .build();
try (Response resp = site.getHttpClient().execute(req)) { Response resp = site.getHttpClient().execute(req);
// do an initial request to get cookies resp.close();
}
String url = null; String url;
if (follow) { if (follow) {
url = getSite().getBaseUrl() + "/follow/follow/" + getName() + "/"; url = getSite().getBaseUrl() + "/follow/follow/" + getName() + "/";
} else { } else {
@ -226,7 +200,7 @@ public class ChaturbateModel extends AbstractModel { // NOSONAR
.header(ACCEPT_LANGUAGE, "en-US,en;q=0.5") .header(ACCEPT_LANGUAGE, "en-US,en;q=0.5")
.header(REFERER, getUrl()) .header(REFERER, getUrl())
.header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent) .header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent)
.header("X-CSRFToken", ((ChaturbateHttpClient)site.getHttpClient()).getToken()) .header("X-CSRFToken", ((ChaturbateHttpClient) site.getHttpClient()).getToken())
.header(X_REQUESTED_WITH, XML_HTTP_REQUEST) .header(X_REQUESTED_WITH, XML_HTTP_REQUEST)
.build(); .build();
try (Response resp2 = site.getHttpClient().execute(req)) { try (Response resp2 = site.getHttpClient().execute(req)) {
@ -246,12 +220,12 @@ public class ChaturbateModel extends AbstractModel { // NOSONAR
} }
} }
private StreamInfo getStreamInfo() throws IOException, InterruptedException { private StreamInfo getStreamInfo() throws IOException {
return getStreamInfo(false); return getStreamInfo(false);
} }
private StreamInfo getStreamInfo(boolean failFast) throws IOException, InterruptedException { private StreamInfo getStreamInfo(boolean failFast) throws IOException {
if(failFast) { if (failFast) {
return streamInfo; return streamInfo;
} else { } else {
return Optional.ofNullable(streamInfo).orElse(loadStreamInfo()); return Optional.ofNullable(streamInfo).orElse(loadStreamInfo());
@ -289,21 +263,21 @@ public class ChaturbateModel extends AbstractModel { // NOSONAR
} }
} }
private int[] getResolution() throws IOException, ParseException, PlaylistException, InterruptedException { private int[] getResolution() throws IOException, ParseException, PlaylistException {
int[] res = new int[2]; int[] res = new int[2];
if(!getStreamInfo().url.startsWith("http")) { if (!getStreamInfo().url.startsWith("http")) {
return res; return res;
} }
EOFException ex = null; EOFException ex = null;
for(int i=0; i<2; i++) { for (int i = 0; i < 2; i++) {
try { try {
MasterPlaylist master = getMasterPlaylist(); MasterPlaylist master = getMasterPlaylist();
for (PlaylistData playlistData : master.getPlaylists()) { for (PlaylistData playlistData : master.getPlaylists()) {
if(playlistData.hasStreamInfo() && playlistData.getStreamInfo().hasResolution()) { if (playlistData.hasStreamInfo() && playlistData.getStreamInfo().hasResolution()) {
int h = playlistData.getStreamInfo().getResolution().height; int h = playlistData.getStreamInfo().getResolution().height;
int w = playlistData.getStreamInfo().getResolution().width; int w = playlistData.getStreamInfo().getResolution().width;
if(w > res[1]) { if (w > res[1]) {
res[0] = w; res[0] = w;
res[1] = h; res[1] = h;
} }
@ -311,21 +285,21 @@ public class ChaturbateModel extends AbstractModel { // NOSONAR
} }
ex = null; ex = null;
break; // this attempt worked, exit loop break; // this attempt worked, exit loop
} catch(EOFException e) { } catch (EOFException e) {
// the cause might be, that the playlist url in streaminfo is outdated, // the cause might be, that the playlist url in streaminfo is outdated,
// so let's remove it from cache and retry in the next iteration // so let's remove it from cache and retry in the next iteration
ex = e; ex = e;
} }
} }
if(ex != null) { if (ex != null) {
throw ex; throw ex;
} }
return res; return res;
} }
public MasterPlaylist getMasterPlaylist() throws IOException, ParseException, PlaylistException, InterruptedException { public MasterPlaylist getMasterPlaylist() throws IOException, ParseException, PlaylistException {
return getMasterPlaylist(getStreamInfo()); return getMasterPlaylist(getStreamInfo());
} }