diff --git a/client/src/main/java/ctbrec/ui/sites/chaturbate/ChaturbateUpdateService.java b/client/src/main/java/ctbrec/ui/sites/chaturbate/ChaturbateUpdateService.java index bc02a013..ea8ad4f3 100644 --- a/client/src/main/java/ctbrec/ui/sites/chaturbate/ChaturbateUpdateService.java +++ b/client/src/main/java/ctbrec/ui/sites/chaturbate/ChaturbateUpdateService.java @@ -1,14 +1,6 @@ package ctbrec.ui.sites.chaturbate; -import java.io.IOException; -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.Config; import ctbrec.Model; import ctbrec.sites.chaturbate.Chaturbate; import ctbrec.sites.chaturbate.ChaturbateModelParser; @@ -16,13 +8,23 @@ import ctbrec.ui.SiteUiFactory; import ctbrec.ui.tabs.PaginatedScheduledService; import javafx.concurrent.Task; 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 { private static final Logger LOG = LoggerFactory.getLogger(ChaturbateUpdateService.class); private String url; - private boolean loginRequired; - private Chaturbate chaturbate; + private final boolean loginRequired; + private final Chaturbate chaturbate; public ChaturbateUpdateService(String url, boolean loginRequired, Chaturbate chaturbate) { this.url = url; @@ -40,18 +42,22 @@ public class ChaturbateUpdateService extends PaginatedScheduledService { @Override protected Task> createTask() { - return new Task>() { + return new Task<>() { @Override public List call() throws IOException { if (loginRequired && !chaturbate.credentialsAvailable()) { return Collections.emptyList(); } 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); - if(loginRequired) { + if (loginRequired) { 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)) { if (response.isSuccessful()) { List models = ChaturbateModelParser.parseModels(chaturbate, response.body().string()); diff --git a/common/src/main/java/ctbrec/sites/chaturbate/ChaturbateModel.java b/common/src/main/java/ctbrec/sites/chaturbate/ChaturbateModel.java index ba19cc1c..b3133dd8 100644 --- a/common/src/main/java/ctbrec/sites/chaturbate/ChaturbateModel.java +++ b/common/src/main/java/ctbrec/sites/chaturbate/ChaturbateModel.java @@ -1,38 +1,11 @@ package ctbrec.sites.chaturbate; -import static ctbrec.Model.State.*; -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.*; import com.iheartradio.m3u8.data.MasterPlaylist; import com.iheartradio.m3u8.data.Playlist; import com.iheartradio.m3u8.data.PlaylistData; import com.squareup.moshi.JsonAdapter; import com.squareup.moshi.Moshi; - import ctbrec.AbstractModel; import ctbrec.Config; import ctbrec.io.HttpException; @@ -41,6 +14,22 @@ import okhttp3.FormBody; import okhttp3.Request; import okhttp3.RequestBody; 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 @@ -50,9 +39,11 @@ public class ChaturbateModel extends AbstractModel { // NOSONAR private transient StreamInfo streamInfo; private transient Instant lastStreamInfoRequest = Instant.EPOCH; + /** * This constructor exists only for deserialization. Please don't call it directly */ + @SuppressWarnings("unused") public ChaturbateModel() { } @@ -76,13 +67,13 @@ public class ChaturbateModel extends AbstractModel { // NOSONAR @Override public int[] getStreamResolution(boolean failFast) throws ExecutionException { - if(failFast) { + if (failFast) { return resolution; } try { resolution = getResolution(); - } catch(Exception e) { + } catch (Exception e) { throw new ExecutionException(e); } return resolution; @@ -115,27 +106,15 @@ public class ChaturbateModel extends AbstractModel { // NOSONAR private void setOnlineStateByRoomStatus(String roomStatus) { if (roomStatus != null) { switch (roomStatus) { - case PUBLIC: - case "Unknown": - onlineState = ONLINE; - break; - case "offline": - onlineState = OFFLINE; - break; - case "private": - 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; + case PUBLIC, "Unknown" -> onlineState = ONLINE; + case "offline" -> onlineState = OFFLINE; + case "private", "hidden", "password protected" -> onlineState = PRIVATE; + case "away" -> onlineState = AWAY; + case "group" -> onlineState = State.GROUP; + 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 { if (!Objects.equals(System.getenv("CTBREC_DEV"), "1")) { 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_room_type", PUBLIC) .build(); Request req = new Request.Builder() - .url("https://chaturbate.com/tipping/send_tip/"+getName()+"/") + .url("https://chaturbate.com/tipping/send_tip/" + getName() + "/") .post(body) - .header(REFERER, "https://chaturbate.com/"+getName()+"/") + .header(REFERER, "https://chaturbate.com/" + getName() + "/") .header(X_REQUESTED_WITH, XML_HTTP_REQUEST) .header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent) .build(); @@ -165,31 +144,26 @@ public class ChaturbateModel extends AbstractModel { // NOSONAR @Override public List getStreamSources() throws IOException, ExecutionException, ParseException, PlaylistException { - try { - streamInfo = loadStreamInfo(); - MasterPlaylist masterPlaylist = getMasterPlaylist(); - List sources = new ArrayList<>(); - for (PlaylistData playlist : masterPlaylist.getPlaylists()) { - if (playlist.hasStreamInfo()) { - StreamSource src = new StreamSource(); - src.bandwidth = playlist.getStreamInfo().getBandwidth(); - src.height = playlist.getStreamInfo().getResolution().height; - String masterUrl = streamInfo.url; - String baseUrl = masterUrl.substring(0, masterUrl.lastIndexOf('/') + 1); - String segmentUri = baseUrl + playlist.getUri(); - src.mediaPlaylistUrl = segmentUri; - if(src.mediaPlaylistUrl.contains("?")) { - src.mediaPlaylistUrl = src.mediaPlaylistUrl.substring(0, src.mediaPlaylistUrl.lastIndexOf('?')); - } - LOG.trace("Media playlist {}", src.mediaPlaylistUrl); - sources.add(src); + streamInfo = loadStreamInfo(); + MasterPlaylist masterPlaylist = getMasterPlaylist(); + List sources = new ArrayList<>(); + for (PlaylistData playlist : masterPlaylist.getPlaylists()) { + if (playlist.hasStreamInfo()) { + StreamSource src = new StreamSource(); + src.bandwidth = playlist.getStreamInfo().getBandwidth(); + src.height = playlist.getStreamInfo().getResolution().height; + String masterUrl = streamInfo.url; + String baseUrl = masterUrl.substring(0, masterUrl.lastIndexOf('/') + 1); + String segmentUri = baseUrl + playlist.getUri(); + src.mediaPlaylistUrl = segmentUri; + if (src.mediaPlaylistUrl.contains("?")) { + src.mediaPlaylistUrl = src.mediaPlaylistUrl.substring(0, src.mediaPlaylistUrl.lastIndexOf('?')); } + LOG.trace("Media playlist {}", src.mediaPlaylistUrl); + sources.add(src); } - return sources; - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new ExecutionException(e); } + return sources; } @Override @@ -203,15 +177,15 @@ public class ChaturbateModel extends AbstractModel { // NOSONAR } private boolean follow(boolean follow) throws IOException { + // do an initial request to get cookies Request req = new Request.Builder() .url(getUrl()) .header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent) .build(); - try (Response resp = site.getHttpClient().execute(req)) { - // do an initial request to get cookies - } + Response resp = site.getHttpClient().execute(req); + resp.close(); - String url = null; + String url; if (follow) { url = getSite().getBaseUrl() + "/follow/follow/" + getName() + "/"; } else { @@ -226,7 +200,7 @@ public class ChaturbateModel extends AbstractModel { // NOSONAR .header(ACCEPT_LANGUAGE, "en-US,en;q=0.5") .header(REFERER, getUrl()) .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) .build(); 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); } - private StreamInfo getStreamInfo(boolean failFast) throws IOException, InterruptedException { - if(failFast) { + private StreamInfo getStreamInfo(boolean failFast) throws IOException { + if (failFast) { return streamInfo; } else { 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]; - if(!getStreamInfo().url.startsWith("http")) { + if (!getStreamInfo().url.startsWith("http")) { return res; } EOFException ex = null; - for(int i=0; i<2; i++) { + for (int i = 0; i < 2; i++) { try { MasterPlaylist master = getMasterPlaylist(); for (PlaylistData playlistData : master.getPlaylists()) { - if(playlistData.hasStreamInfo() && playlistData.getStreamInfo().hasResolution()) { + if (playlistData.hasStreamInfo() && playlistData.getStreamInfo().hasResolution()) { int h = playlistData.getStreamInfo().getResolution().height; int w = playlistData.getStreamInfo().getResolution().width; - if(w > res[1]) { + if (w > res[1]) { res[0] = w; res[1] = h; } @@ -311,21 +285,21 @@ public class ChaturbateModel extends AbstractModel { // NOSONAR } ex = null; break; // this attempt worked, exit loop - } catch(EOFException e) { + } catch (EOFException e) { // 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 ex = e; } } - if(ex != null) { + if (ex != null) { throw ex; } return res; } - public MasterPlaylist getMasterPlaylist() throws IOException, ParseException, PlaylistException, InterruptedException { + public MasterPlaylist getMasterPlaylist() throws IOException, ParseException, PlaylistException { return getMasterPlaylist(getStreamInfo()); }