diff --git a/src/main/java/ctbrec/io/HttpException.java b/src/main/java/ctbrec/io/HttpException.java new file mode 100644 index 00000000..e9664bf5 --- /dev/null +++ b/src/main/java/ctbrec/io/HttpException.java @@ -0,0 +1,23 @@ +package ctbrec.io; + +import java.io.IOException; + +public class HttpException extends IOException { + + private int code; + private String msg; + + public HttpException(int code, String msg) { + super(code + " - " + msg); + this.code = code; + this.msg = msg; + } + + public int getResponseCode() { + return code; + } + + public String getResponseMessage() { + return msg; + } +} diff --git a/src/main/java/ctbrec/recorder/LocalRecorder.java b/src/main/java/ctbrec/recorder/LocalRecorder.java index 81c6c128..51de573f 100644 --- a/src/main/java/ctbrec/recorder/LocalRecorder.java +++ b/src/main/java/ctbrec/recorder/LocalRecorder.java @@ -33,6 +33,7 @@ import ctbrec.Config; import ctbrec.Model; import ctbrec.OS; import ctbrec.Recording; +import ctbrec.io.HttpException; import ctbrec.io.StreamRedirectThread; import ctbrec.recorder.PlaylistGenerator.InvalidPlaylistException; import ctbrec.recorder.download.Download; @@ -408,6 +409,9 @@ public class LocalRecorder implements Recorder { startRecordingProcess(model); } } + } catch (HttpException e) { + LOG.error("Couldn't check if model {} is online. HTTP Response: {} - {}", + model.getName(), e.getResponseCode(), e.getResponseMessage()); } catch (Exception e) { LOG.error("Couldn't check if model {} is online", model.getName(), e); } diff --git a/src/main/java/ctbrec/recorder/RemoteRecorder.java b/src/main/java/ctbrec/recorder/RemoteRecorder.java index 957906c1..84d1a38e 100644 --- a/src/main/java/ctbrec/recorder/RemoteRecorder.java +++ b/src/main/java/ctbrec/recorder/RemoteRecorder.java @@ -19,6 +19,7 @@ import ctbrec.Hmac; import ctbrec.Model; import ctbrec.Recording; import ctbrec.io.HttpClient; +import ctbrec.io.HttpException; import ctbrec.io.InstantJsonAdapter; import ctbrec.io.ModelJsonAdapter; import ctbrec.sites.Site; @@ -79,21 +80,22 @@ public class RemoteRecorder implements Recorder { .post(body); addHmacIfNeeded(payload, builder); Request request = builder.build(); - Response response = client.execute(request); - String json = response.body().string(); - if(response.isSuccessful()) { - ModelListResponse resp = modelListResponseAdapter.fromJson(json); - if(!resp.status.equals("success")) { - throw new IOException("Server returned error " + resp.status + " " + resp.msg); - } + try (Response response = client.execute(request)) { + String json = response.body().string(); + if (response.isSuccessful()) { + ModelListResponse resp = modelListResponseAdapter.fromJson(json); + if (!resp.status.equals("success")) { + throw new IOException("Server returned error " + resp.status + " " + resp.msg); + } - if("start".equals(action)) { - models.add(model); - } else if("stop".equals(action)) { - models.remove(model); + if ("start".equals(action)) { + models.add(model); + } else if ("stop".equals(action)) { + models.remove(model); + } + } else { + throw new HttpException(response.code(), response.message()); } - } else { - throw new IOException("Server returned error. HTTP status: " + response.code()); } } @@ -161,25 +163,26 @@ public class RemoteRecorder implements Recorder { .post(body); addHmacIfNeeded(msg, builder); Request request = builder.build(); - Response response = client.execute(request); - String json = response.body().string(); - if(response.isSuccessful()) { - ModelListResponse resp = modelListResponseAdapter.fromJson(json); - if(resp.status.equals("success")) { - models = resp.models; - for (Model model : models) { - for (Site site : sites) { - if(site.isSiteForModel(model)) { - model.setSite(site); + try(Response response = client.execute(request)) { + String json = response.body().string(); + if(response.isSuccessful()) { + ModelListResponse resp = modelListResponseAdapter.fromJson(json); + if(resp.status.equals("success")) { + models = resp.models; + for (Model model : models) { + for (Site site : sites) { + if(site.isSiteForModel(model)) { + model.setSite(site); + } } } + lastSync = Instant.now(); + } else { + LOG.error("Server returned error: {} - {}", resp.status, resp.msg); } - lastSync = Instant.now(); } else { - LOG.error("Server returned error: {} - {}", resp.status, resp.msg); + LOG.error("Couldn't synchronize with server. HTTP status: {} - {}", response.code(), json); } - } else { - LOG.error("Couldn't synchronize with server. HTTP status: {} - {}", response.code(), json); } } catch (IOException | InvalidKeyException | NoSuchAlgorithmException | IllegalStateException e) { LOG.error("Couldn't synchronize with server", e); @@ -195,24 +198,25 @@ public class RemoteRecorder implements Recorder { .post(body); addHmacIfNeeded(msg, builder); Request request = builder.build(); - Response response = client.execute(request); - String json = response.body().string(); - if(response.isSuccessful()) { - ModelListResponse resp = modelListResponseAdapter.fromJson(json); - if(resp.status.equals("success")) { - onlineModels = resp.models; - for (Model model : models) { - for (Site site : sites) { - if(site.isSiteForModel(model)) { - model.setSite(site); + try (Response response = client.execute(request)) { + String json = response.body().string(); + if (response.isSuccessful()) { + ModelListResponse resp = modelListResponseAdapter.fromJson(json); + if (resp.status.equals("success")) { + onlineModels = resp.models; + for (Model model : models) { + for (Site site : sites) { + if (site.isSiteForModel(model)) { + model.setSite(site); + } } } + } else { + LOG.error("Server returned error: {} - {}", resp.status, resp.msg); } } else { - LOG.error("Server returned error: {} - {}", resp.status, resp.msg); + LOG.error("Couldn't synchronize with server. HTTP status: {} - {}", response.code(), json); } - } else { - LOG.error("Couldn't synchronize with server. HTTP status: {} - {}", response.code(), json); } } catch (IOException | InvalidKeyException | NoSuchAlgorithmException | IllegalStateException e) { LOG.error("Couldn't synchronize with server", e); @@ -254,20 +258,20 @@ public class RemoteRecorder implements Recorder { .post(body); addHmacIfNeeded(msg, builder); Request request = builder.build(); - Response response = client.execute(request); - String json = response.body().string(); - if(response.isSuccessful()) { - RecordingListResponse resp = recordingListResponseAdapter.fromJson(json); - if(resp.status.equals("success")) { - List recordings = resp.recordings; - return recordings; + try(Response response = client.execute(request)) { + String json = response.body().string(); + if(response.isSuccessful()) { + RecordingListResponse resp = recordingListResponseAdapter.fromJson(json); + if(resp.status.equals("success")) { + List recordings = resp.recordings; + return recordings; + } else { + LOG.error("Server returned error: {} - {}", resp.status, resp.msg); + } } else { - LOG.error("Server returned error: {} - {}", resp.status, resp.msg); + LOG.error("Couldn't synchronize with server. HTTP status: {} - {}", response.code(), json); } - } else { - LOG.error("Couldn't synchronize with server. HTTP status: {} - {}", response.code(), json); } - return Collections.emptyList(); } @@ -280,16 +284,16 @@ public class RemoteRecorder implements Recorder { .post(body); addHmacIfNeeded(msg, builder); Request request = builder.build(); - Response response = client.execute(request); - String json = response.body().string(); - RecordingListResponse resp = recordingListResponseAdapter.fromJson(json); - if(response.isSuccessful()) { - if(!resp.status.equals("success")) { + try(Response response = client.execute(request)) { + String json = response.body().string(); + RecordingListResponse resp = recordingListResponseAdapter.fromJson(json); + if(response.isSuccessful()) { + if(!resp.status.equals("success")) { + throw new IOException("Couldn't delete recording: " + resp.msg); + } + } else { throw new IOException("Couldn't delete recording: " + resp.msg); } - } else { - throw new IOException("Couldn't delete recording: " + resp.msg); - //throw new IOException("Couldn't delete recording: " + response.code() + " " + json); } } diff --git a/src/main/java/ctbrec/sites/bonga/BongaCams.java b/src/main/java/ctbrec/sites/bonga/BongaCams.java index f5e51a7d..cad99f0a 100644 --- a/src/main/java/ctbrec/sites/bonga/BongaCams.java +++ b/src/main/java/ctbrec/sites/bonga/BongaCams.java @@ -7,6 +7,7 @@ import org.json.JSONObject; import ctbrec.Config; import ctbrec.Model; import ctbrec.io.HttpClient; +import ctbrec.io.HttpException; import ctbrec.recorder.Recorder; import ctbrec.sites.AbstractSite; import ctbrec.sites.ConfigUI; @@ -89,7 +90,7 @@ public class BongaCams extends AbstractSite { throw new IOException("Request was not successful: " + json.toString(2)); } } else { - throw new IOException(response.code() + " " + response.message()); + throw new HttpException(response.code(), response.message()); } } } diff --git a/src/main/java/ctbrec/sites/bonga/BongaCamsHttpClient.java b/src/main/java/ctbrec/sites/bonga/BongaCamsHttpClient.java index 4606f830..b082b127 100644 --- a/src/main/java/ctbrec/sites/bonga/BongaCamsHttpClient.java +++ b/src/main/java/ctbrec/sites/bonga/BongaCamsHttpClient.java @@ -17,6 +17,7 @@ import org.slf4j.LoggerFactory; import ctbrec.Config; import ctbrec.io.HttpClient; +import ctbrec.io.HttpException; import javafx.application.Platform; import okhttp3.Cookie; import okhttp3.FormBody; @@ -144,7 +145,7 @@ public class BongaCamsHttpClient extends HttpClient { throw new IOException("Request was not successful: " + json.toString(2)); } } else { - throw new IOException(response.code() + " " + response.message()); + throw new HttpException(response.code(), response.message()); } } } @@ -174,7 +175,7 @@ public class BongaCamsHttpClient extends HttpClient { throw new IOException("Request was not successful: " + content); } } else { - throw new IOException(response.code() + ' ' + response.message()); + throw new HttpException(response.code(), response.message()); } } } @@ -229,7 +230,7 @@ public class BongaCamsHttpClient extends HttpClient { // throw new IOException("Login not successful"); // } // } else { - // throw new IOException(response.code() + " " + response.message()); + // throw new HttpException(response.code(), response.message()); // } // } // } diff --git a/src/main/java/ctbrec/sites/cam4/Cam4FollowedUpdateService.java b/src/main/java/ctbrec/sites/cam4/Cam4FollowedUpdateService.java index c752fb4a..a3757293 100644 --- a/src/main/java/ctbrec/sites/cam4/Cam4FollowedUpdateService.java +++ b/src/main/java/ctbrec/sites/cam4/Cam4FollowedUpdateService.java @@ -16,6 +16,7 @@ import org.slf4j.LoggerFactory; import ctbrec.Config; import ctbrec.Model; +import ctbrec.io.HttpException; import ctbrec.ui.HtmlParser; import ctbrec.ui.PaginatedScheduledService; import javafx.concurrent.Task; @@ -51,33 +52,32 @@ public class Cam4FollowedUpdateService extends PaginatedScheduledService { String username = Config.getInstance().getSettings().cam4Username; String url = site.getBaseUrl() + '/' + username + "/edit/friends_favorites"; Request req = new Request.Builder().url(url).build(); - Response response = site.getHttpClient().execute(req, true); - if(response.isSuccessful()) { - String content = response.body().string(); - Elements cells = HtmlParser.getTags(content, "div#favorites div.ff_thumb"); - for (Element cell : cells) { - String cellHtml = cell.html(); - Element link = HtmlParser.getTag(cellHtml, "div.ff_img a"); - String path = link.attr("href"); - String modelName = path.substring(1); - Cam4Model model = (Cam4Model) site.createModel(modelName); - model.setPreview("https://snapshots.xcdnpro.com/thumbnails/"+model.getName()+"?s=" + System.currentTimeMillis()); - model.setOnlineState(parseOnlineState(cellHtml)); - models.add(model); + try(Response response = site.getHttpClient().execute(req, true)) { + if(response.isSuccessful()) { + String content = response.body().string(); + Elements cells = HtmlParser.getTags(content, "div#favorites div.ff_thumb"); + for (Element cell : cells) { + String cellHtml = cell.html(); + Element link = HtmlParser.getTag(cellHtml, "div.ff_img a"); + String path = link.attr("href"); + String modelName = path.substring(1); + Cam4Model model = (Cam4Model) site.createModel(modelName); + model.setPreview("https://snapshots.xcdnpro.com/thumbnails/"+model.getName()+"?s=" + System.currentTimeMillis()); + model.setOnlineState(parseOnlineState(cellHtml)); + models.add(model); + } + return models.stream() + .filter(m -> { + try { + return m.isOnline() == showOnline; + } catch (IOException | ExecutionException | InterruptedException e) { + LOG.error("Couldn't determine online state", e); + return false; + } + }).collect(Collectors.toList()); + } else { + throw new HttpException(response.code(), response.message()); } - return models.stream() - .filter(m -> { - try { - return m.isOnline() == showOnline; - } catch (IOException | ExecutionException | InterruptedException e) { - LOG.error("Couldn't determine online state", e); - return false; - } - }).collect(Collectors.toList()); - } else { - IOException e = new IOException(response.code() + " " + response.message()); - response.close(); - throw e; } } diff --git a/src/main/java/ctbrec/sites/cam4/Cam4Model.java b/src/main/java/ctbrec/sites/cam4/Cam4Model.java index 822b53b5..1e7c05e1 100644 --- a/src/main/java/ctbrec/sites/cam4/Cam4Model.java +++ b/src/main/java/ctbrec/sites/cam4/Cam4Model.java @@ -24,6 +24,7 @@ import com.iheartradio.m3u8.data.PlaylistData; import ctbrec.AbstractModel; import ctbrec.Config; +import ctbrec.io.HttpException; import ctbrec.recorder.download.StreamSource; import ctbrec.sites.Site; import ctbrec.ui.CamrecApplication; @@ -62,24 +63,23 @@ public class Cam4Model extends AbstractModel { String url = site.getBaseUrl() + "/getBroadcasting?usernames=" + getName(); LOG.trace("Loading model details {}", url); Request req = new Request.Builder().url(url).build(); - Response response = site.getHttpClient().execute(req); - if(response.isSuccessful()) { - JSONArray json = new JSONArray(response.body().string()); - if(json.length() == 0) { - throw new ModelDetailsEmptyException("Model details are empty"); + try(Response response = site.getHttpClient().execute(req)) { + if(response.isSuccessful()) { + JSONArray json = new JSONArray(response.body().string()); + if(json.length() == 0) { + throw new ModelDetailsEmptyException("Model details are empty"); + } + JSONObject details = json.getJSONObject(0); + onlineState = details.getString("showType"); + playlistUrl = details.getString("hlsPreviewUrl"); + if(details.has("resolution")) { + String res = details.getString("resolution"); + String[] tokens = res.split(":"); + resolution = new int[] {Integer.parseInt(tokens[0]), Integer.parseInt(tokens[1])}; + } + } else { + throw new HttpException(response.code(), response.message()); } - JSONObject details = json.getJSONObject(0); - onlineState = details.getString("showType"); - playlistUrl = details.getString("hlsPreviewUrl"); - if(details.has("resolution")) { - String res = details.getString("resolution"); - String[] tokens = res.split(":"); - resolution = new int[] {Integer.parseInt(tokens[0]), Integer.parseInt(tokens[1])}; - } - } else { - IOException io = new IOException(response.code() + " " + response.message()); - response.close(); - throw io; } } @@ -185,40 +185,40 @@ public class Cam4Model extends AbstractModel { // we have to use a client without any cam4 cookies here, otherwise // this request is redirected to the login page. no idea why - Response response = CamrecApplication.httpClient.execute(req); - String broadCasterId = null; - if(response.isSuccessful()) { - String content = response.body().string(); - try { - Element tag = HtmlParser.getTag(content, "input[name=\"broadcasterId\"]"); - broadCasterId = tag.attr("value"); - } catch(Exception e) { - LOG.debug(content); - throw new IOException(e); - } - - // send unfollow request - String username = Config.getInstance().getSettings().cam4Username; - url = site.getBaseUrl() + '/' + username + "/edit/friends_favorites"; - RequestBody body = new FormBody.Builder() - .add("deleteFavorites", broadCasterId) - .add("simpleresult", "true") - .build(); - req = new Request.Builder() - .url(url) - .post(body) - .addHeader("X-Requested-With", "XMLHttpRequest") - .build(); - response = site.getHttpClient().execute(req, true); + try(Response response = CamrecApplication.httpClient.execute(req)) { + String broadCasterId = null; if(response.isSuccessful()) { - return Objects.equals(response.body().string(), "Ok"); + String content = response.body().string(); + try { + Element tag = HtmlParser.getTag(content, "input[name=\"broadcasterId\"]"); + broadCasterId = tag.attr("value"); + } catch(Exception e) { + LOG.debug(content); + throw new IOException(e); + } + + // send unfollow request + String username = Config.getInstance().getSettings().cam4Username; + url = site.getBaseUrl() + '/' + username + "/edit/friends_favorites"; + RequestBody body = new FormBody.Builder() + .add("deleteFavorites", broadCasterId) + .add("simpleresult", "true") + .build(); + req = new Request.Builder() + .url(url) + .post(body) + .addHeader("X-Requested-With", "XMLHttpRequest") + .build(); + Response resp = site.getHttpClient().execute(req, true); + if(resp.isSuccessful()) { + return Objects.equals(resp.body().string(), "Ok"); + } else { + resp.close(); + return false; + } } else { - response.close(); return false; } - } else { - response.close(); - return false; } } diff --git a/src/main/java/ctbrec/sites/cam4/Cam4UpdateService.java b/src/main/java/ctbrec/sites/cam4/Cam4UpdateService.java index bcd89205..da6ea05f 100644 --- a/src/main/java/ctbrec/sites/cam4/Cam4UpdateService.java +++ b/src/main/java/ctbrec/sites/cam4/Cam4UpdateService.java @@ -17,6 +17,7 @@ import org.slf4j.LoggerFactory; import ctbrec.Config; import ctbrec.Model; +import ctbrec.io.HttpException; import ctbrec.ui.HtmlParser; import ctbrec.ui.PaginatedScheduledService; import javafx.concurrent.Task; @@ -58,30 +59,28 @@ public class Cam4UpdateService extends PaginatedScheduledService { String url = Cam4UpdateService.this.url + "&page=" + page; LOG.debug("Fetching page {}", url); Request request = new Request.Builder().url(url).build(); - Response response = site.getHttpClient().execute(request, loginRequired); - if (response.isSuccessful()) { - JSONObject json = new JSONObject(response.body().string()); - String html = json.getString("html"); - Elements profilesBoxes = HtmlParser.getTags(html, "div[class~=profileDataBox]"); - List models = new ArrayList<>(profilesBoxes.size()); - for (Element profileBox : profilesBoxes) { - String boxHtml = profileBox.html(); - Element profileLink = HtmlParser.getTag(boxHtml, "a.profile-preview"); - String path = profileLink.attr("href"); - String slug = path.substring(1); - Cam4Model model = (Cam4Model) site.createModel(slug); - String playlistUrl = profileLink.attr("data-hls-preview-url"); - model.setPlaylistUrl(playlistUrl); - model.setPreview("https://snapshots.xcdnpro.com/thumbnails/"+model.getName()+"?s=" + System.currentTimeMillis()); - model.setDescription(parseDesription(boxHtml)); - models.add(model); + try (Response response = site.getHttpClient().execute(request, loginRequired)) { + if (response.isSuccessful()) { + JSONObject json = new JSONObject(response.body().string()); + String html = json.getString("html"); + Elements profilesBoxes = HtmlParser.getTags(html, "div[class~=profileDataBox]"); + List models = new ArrayList<>(profilesBoxes.size()); + for (Element profileBox : profilesBoxes) { + String boxHtml = profileBox.html(); + Element profileLink = HtmlParser.getTag(boxHtml, "a.profile-preview"); + String path = profileLink.attr("href"); + String slug = path.substring(1); + Cam4Model model = (Cam4Model) site.createModel(slug); + String playlistUrl = profileLink.attr("data-hls-preview-url"); + model.setPlaylistUrl(playlistUrl); + model.setPreview("https://snapshots.xcdnpro.com/thumbnails/" + model.getName() + "?s=" + System.currentTimeMillis()); + model.setDescription(parseDesription(boxHtml)); + models.add(model); + } + return models; + } else { + throw new HttpException(response.code(), response.message()); } - response.close(); - return models; - } else { - int code = response.code(); - response.close(); - throw new IOException("HTTP status " + code); } } } diff --git a/src/main/java/ctbrec/sites/camsoda/Camsoda.java b/src/main/java/ctbrec/sites/camsoda/Camsoda.java index 1ae7f00c..e3c813ab 100644 --- a/src/main/java/ctbrec/sites/camsoda/Camsoda.java +++ b/src/main/java/ctbrec/sites/camsoda/Camsoda.java @@ -7,6 +7,7 @@ import org.json.JSONObject; import ctbrec.Config; import ctbrec.Model; import ctbrec.io.HttpClient; +import ctbrec.io.HttpException; import ctbrec.recorder.Recorder; import ctbrec.sites.AbstractSite; import ctbrec.sites.ConfigUI; @@ -72,17 +73,18 @@ public class Camsoda extends AbstractSite { String username = Config.getInstance().getSettings().camsodaUsername; String url = BASE_URI + "/api/v1/user/" + username; Request request = new Request.Builder().url(url).build(); - Response response = getHttpClient().execute(request, true); - if(response.isSuccessful()) { - JSONObject json = new JSONObject(response.body().string()); - if(json.has("user")) { - JSONObject user = json.getJSONObject("user"); - if(user.has("tokens")) { - return user.getInt("tokens"); + try(Response response = getHttpClient().execute(request, true)) { + if(response.isSuccessful()) { + JSONObject json = new JSONObject(response.body().string()); + if(json.has("user")) { + JSONObject user = json.getJSONObject("user"); + if(user.has("tokens")) { + return user.getInt("tokens"); + } } + } else { + throw new HttpException(response.code(), response.message()); } - } else { - throw new IOException(response.code() + " " + response.message()); } throw new RuntimeException("Tokens not found in response"); } diff --git a/src/main/java/ctbrec/sites/camsoda/CamsodaFollowedUpdateService.java b/src/main/java/ctbrec/sites/camsoda/CamsodaFollowedUpdateService.java index 20c4bbe0..16b45af7 100644 --- a/src/main/java/ctbrec/sites/camsoda/CamsodaFollowedUpdateService.java +++ b/src/main/java/ctbrec/sites/camsoda/CamsodaFollowedUpdateService.java @@ -11,6 +11,7 @@ import org.json.JSONArray; import org.json.JSONObject; import ctbrec.Model; +import ctbrec.io.HttpException; import ctbrec.ui.PaginatedScheduledService; import javafx.concurrent.Task; import okhttp3.Request; @@ -32,36 +33,35 @@ public class CamsodaFollowedUpdateService extends PaginatedScheduledService { List models = new ArrayList<>(); String url = camsoda.getBaseUrl() + "/api/v1/user/current"; Request request = new Request.Builder().url(url).build(); - Response response = camsoda.getHttpClient().execute(request, true); - if (response.isSuccessful()) { - JSONObject json = new JSONObject(response.body().string()); - if(json.has("status") && json.getBoolean("status")) { - JSONObject user = json.getJSONObject("user"); - JSONArray following = user.getJSONArray("following"); - for (int i = 0; i < following.length(); i++) { - JSONObject m = following.getJSONObject(i); - CamsodaModel model = (CamsodaModel) camsoda.createModel(m.getString("followname")); - boolean online = m.getInt("online") == 1; - model.setOnlineState(online ? "online" : "offline"); - model.setPreview("https://md.camsoda.com/thumbs/" + model.getName() + ".jpg"); - models.add(model); + try(Response response = camsoda.getHttpClient().execute(request, true)) { + if (response.isSuccessful()) { + JSONObject json = new JSONObject(response.body().string()); + if(json.has("status") && json.getBoolean("status")) { + JSONObject user = json.getJSONObject("user"); + JSONArray following = user.getJSONArray("following"); + for (int i = 0; i < following.length(); i++) { + JSONObject m = following.getJSONObject(i); + CamsodaModel model = (CamsodaModel) camsoda.createModel(m.getString("followname")); + boolean online = m.getInt("online") == 1; + model.setOnlineState(online ? "online" : "offline"); + model.setPreview("https://md.camsoda.com/thumbs/" + model.getName() + ".jpg"); + models.add(model); + } + return models.stream() + .filter((m) -> { + try { + return m.isOnline() == showOnline; + } catch (IOException | ExecutionException | InterruptedException e) { + return false; + } + }).collect(Collectors.toList()); + } else { + response.close(); + return Collections.emptyList(); } - return models.stream() - .filter((m) -> { - try { - return m.isOnline() == showOnline; - } catch (IOException | ExecutionException | InterruptedException e) { - return false; - } - }).collect(Collectors.toList()); } else { - response.close(); - return Collections.emptyList(); + throw new HttpException(response.code(), response.message()); } - } else { - int code = response.code(); - response.close(); - throw new IOException("HTTP status " + code); } } }; diff --git a/src/main/java/ctbrec/sites/camsoda/CamsodaHttpClient.java b/src/main/java/ctbrec/sites/camsoda/CamsodaHttpClient.java index fbb90d6c..d4905bbf 100644 --- a/src/main/java/ctbrec/sites/camsoda/CamsodaHttpClient.java +++ b/src/main/java/ctbrec/sites/camsoda/CamsodaHttpClient.java @@ -15,6 +15,7 @@ import org.slf4j.LoggerFactory; import ctbrec.Config; import ctbrec.io.HttpClient; +import ctbrec.io.HttpException; import ctbrec.sites.cam4.Cam4LoginDialog; import ctbrec.ui.HtmlParser; import javafx.application.Platform; @@ -55,22 +56,23 @@ public class CamsodaHttpClient extends HttpClient { .url(url) .post(body) .build(); - Response response = execute(request); - if(response.isSuccessful()) { - JSONObject resp = new JSONObject(response.body().string()); - if(resp.has("error")) { - String error = resp.getString("error"); - if (Objects.equals(error, "Please confirm that you are not a robot.")) { - //return loginWithDialog(); - throw new IOException("CamSoda requested to solve a captcha. Please try again in a while (maybe 15 min)."); + try (Response response = execute(request)) { + if (response.isSuccessful()) { + JSONObject resp = new JSONObject(response.body().string()); + if (resp.has("error")) { + String error = resp.getString("error"); + if (Objects.equals(error, "Please confirm that you are not a robot.")) { + // return loginWithDialog(); + throw new IOException("CamSoda requested to solve a captcha. Please try again in a while (maybe 15 min)."); + } else { + throw new IOException(resp.getString("error")); + } } else { - throw new IOException(resp.getString("error")); + return true; } } else { - return true; + throw new HttpException(response.code(), response.message()); } - } else { - throw new IOException(response.code() + " " + response.message()); } } @@ -147,14 +149,13 @@ public class CamsodaHttpClient extends HttpClient { if(csrfToken == null) { String url = Camsoda.BASE_URI; Request request = new Request.Builder().url(url).build(); - Response resp = execute(request, true); - if(resp.isSuccessful()) { - Element meta = HtmlParser.getTag(resp.body().string(), "meta[name=\"_token\"]"); - csrfToken = meta.attr("content"); - } else { - IOException e = new IOException(resp.code() + " " + resp.message()); - resp.close(); - throw e; + try(Response response = execute(request, true)) { + if(response.isSuccessful()) { + Element meta = HtmlParser.getTag(response.body().string(), "meta[name=\"_token\"]"); + csrfToken = meta.attr("content"); + } else { + throw new HttpException(response.code(), response.message()); + } } } return csrfToken; diff --git a/src/main/java/ctbrec/sites/camsoda/CamsodaModel.java b/src/main/java/ctbrec/sites/camsoda/CamsodaModel.java index fb2b7aff..ef45e4e7 100644 --- a/src/main/java/ctbrec/sites/camsoda/CamsodaModel.java +++ b/src/main/java/ctbrec/sites/camsoda/CamsodaModel.java @@ -26,6 +26,7 @@ import com.iheartradio.m3u8.data.StreamInfo; import ctbrec.AbstractModel; import ctbrec.Config; +import ctbrec.io.HttpException; import ctbrec.recorder.download.StreamSource; import ctbrec.sites.Site; import okhttp3.FormBody; @@ -189,7 +190,7 @@ public class CamsodaModel extends AbstractModel { .build(); try(Response response = site.getHttpClient().execute(request, true)) { if(!response.isSuccessful()) { - throw new IOException("HTTP status " + response.code() + " " + response.message()); + throw new HttpException(response.code(), response.message()); } } } @@ -209,13 +210,12 @@ public class CamsodaModel extends AbstractModel { .addHeader("Accept-Language", "en") .addHeader("X-CSRF-Token", csrfToken) .build(); - Response resp = site.getHttpClient().execute(request, true); - if (resp.isSuccessful()) { - resp.close(); - return true; - } else { - resp.close(); - throw new IOException("HTTP status " + resp.code() + " " + resp.message()); + try(Response response = site.getHttpClient().execute(request, true)) { + if (response.isSuccessful()) { + return true; + } else { + throw new HttpException(response.code(), response.message()); + } } } @@ -233,13 +233,12 @@ public class CamsodaModel extends AbstractModel { .addHeader("Accept-Language", "en") .addHeader("X-CSRF-Token", csrfToken) .build(); - Response resp = site.getHttpClient().execute(request, true); - if (resp.isSuccessful()) { - resp.close(); - return true; - } else { - resp.close(); - throw new IOException("HTTP status " + resp.code() + " " + resp.message()); + try (Response response = site.getHttpClient().execute(request, true)) { + if (response.isSuccessful()) { + return true; + } else { + throw new HttpException(response.code(), response.message()); + } } } diff --git a/src/main/java/ctbrec/sites/camsoda/CamsodaShowsTab.java b/src/main/java/ctbrec/sites/camsoda/CamsodaShowsTab.java index 3557a55a..2991af45 100644 --- a/src/main/java/ctbrec/sites/camsoda/CamsodaShowsTab.java +++ b/src/main/java/ctbrec/sites/camsoda/CamsodaShowsTab.java @@ -82,30 +82,30 @@ public class CamsodaShowsTab extends Tab implements TabSelectionListener { protected List call() throws Exception { String url = camsoda.getBaseUrl() + "/api/v1/user/model_shows"; Request req = new Request.Builder().url(url).build(); - Response response = camsoda.getHttpClient().execute(req); - if (response.isSuccessful()) { - JSONObject json = new JSONObject(response.body().string()); - if (json.optInt("success") == 1) { - List boxes = new ArrayList<>(); - JSONArray results = json.getJSONArray("results"); - for (int i = 0; i < results.length(); i++) { - JSONObject result = results.getJSONObject(i); - String modelUrl = camsoda.getBaseUrl() + result.getString("url"); - String name = modelUrl.substring(modelUrl.lastIndexOf('/') + 1); - Model model = camsoda.createModel(name); - ZonedDateTime startTime = parseUtcTime(result.getString("start")); - ZonedDateTime endTime = parseUtcTime(result.getString("end")); - boxes.add(new ShowBox(model, startTime, endTime)); + try(Response response = camsoda.getHttpClient().execute(req)) { + if (response.isSuccessful()) { + JSONObject json = new JSONObject(response.body().string()); + if (json.optInt("success") == 1) { + List boxes = new ArrayList<>(); + JSONArray results = json.getJSONArray("results"); + for (int i = 0; i < results.length(); i++) { + JSONObject result = results.getJSONObject(i); + String modelUrl = camsoda.getBaseUrl() + result.getString("url"); + String name = modelUrl.substring(modelUrl.lastIndexOf('/') + 1); + Model model = camsoda.createModel(name); + ZonedDateTime startTime = parseUtcTime(result.getString("start")); + ZonedDateTime endTime = parseUtcTime(result.getString("end")); + boxes.add(new ShowBox(model, startTime, endTime)); + } + return boxes; + } else { + LOG.error("Couldn't load upcoming camsoda shows. Unexpected response: {}", json.toString()); + showErrorDialog("Oh no!", "Couldn't load upcoming CamSoda shows", "Got an unexpected response from server"); } - return boxes; } else { - LOG.error("Couldn't load upcoming camsoda shows. Unexpected response: {}", json.toString()); showErrorDialog("Oh no!", "Couldn't load upcoming CamSoda shows", "Got an unexpected response from server"); + LOG.error("Couldn't load upcoming camsoda shows: {} {}", response.code(), response.message()); } - } else { - response.close(); - showErrorDialog("Oh no!", "Couldn't load upcoming CamSoda shows", "Got an unexpected response from server"); - LOG.error("Couldn't load upcoming camsoda shows: {} {}", response.code(), response.message()); } return Collections.emptyList(); } diff --git a/src/main/java/ctbrec/sites/camsoda/CamsodaUpdateService.java b/src/main/java/ctbrec/sites/camsoda/CamsodaUpdateService.java index a43f9332..c76b3c28 100644 --- a/src/main/java/ctbrec/sites/camsoda/CamsodaUpdateService.java +++ b/src/main/java/ctbrec/sites/camsoda/CamsodaUpdateService.java @@ -13,6 +13,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ctbrec.Model; +import ctbrec.io.HttpException; import ctbrec.ui.PaginatedScheduledService; import javafx.concurrent.Task; import okhttp3.Request; @@ -45,76 +46,71 @@ public class CamsodaUpdateService extends PaginatedScheduledService { String url = CamsodaUpdateService.this.url; LOG.debug("Fetching page {}", url); Request request = new Request.Builder().url(url).build(); - Response response = camsoda.getHttpClient().execute(request, loginRequired); - if (response.isSuccessful()) { - JSONObject json = new JSONObject(response.body().string()); - if(json.has("status") && json.getBoolean("status")) { - JSONArray results = json.getJSONArray("results"); - for (int i = 0; i < results.length(); i++) { - JSONObject result = results.getJSONObject(i); - if(result.has("tpl")) { - JSONArray tpl = result.getJSONArray("tpl"); - String name = tpl.getString(0); - // int connections = tpl.getInt(2); - String streamName = tpl.getString(5); - String tsize = tpl.getString(6); - String serverPrefix = tpl.getString(7); - CamsodaModel model = (CamsodaModel) camsoda.createModel(name); - model.setDescription(tpl.getString(4)); - model.setSortOrder(tpl.getFloat(3)); - long unixtime = System.currentTimeMillis() / 1000; - String preview = "https://thumbs-orig.camsoda.com/thumbs/" - + streamName + '/' + serverPrefix + '/' + tsize + '/' + unixtime + '/' + name + ".jpg?cb=" + unixtime; - model.setPreview(preview); - if(result.has("edge_servers")) { - JSONArray edgeServers = result.getJSONArray("edge_servers"); - model.setStreamUrl("https://" + edgeServers.getString(0) + "/cam/mp4:" + streamName + "_h264_aac_480p/playlist.m3u8"); - } - models.add(model); - } else { - //LOG.debug("{}", result.toString(2)); - String name = result.getString("username"); - CamsodaModel model = (CamsodaModel) camsoda.createModel(name); - - - if(result.has("server_prefix")) { - String serverPrefix = result.getString("server_prefix"); - String streamName = result.getString("stream_name"); - model.setSortOrder(result.getFloat("sort_value")); - models.add(model); - if(result.has("status")) { - model.setOnlineState(result.getString("status")); - } - + try(Response response = camsoda.getHttpClient().execute(request, loginRequired)) { + if (response.isSuccessful()) { + JSONObject json = new JSONObject(response.body().string()); + if(json.has("status") && json.getBoolean("status")) { + JSONArray results = json.getJSONArray("results"); + for (int i = 0; i < results.length(); i++) { + JSONObject result = results.getJSONObject(i); + if(result.has("tpl")) { + JSONArray tpl = result.getJSONArray("tpl"); + String name = tpl.getString(0); + // int connections = tpl.getInt(2); + String streamName = tpl.getString(5); + String tsize = tpl.getString(6); + String serverPrefix = tpl.getString(7); + CamsodaModel model = (CamsodaModel) camsoda.createModel(name); + model.setDescription(tpl.getString(4)); + model.setSortOrder(tpl.getFloat(3)); + long unixtime = System.currentTimeMillis() / 1000; + String preview = "https://thumbs-orig.camsoda.com/thumbs/" + + streamName + '/' + serverPrefix + '/' + tsize + '/' + unixtime + '/' + name + ".jpg?cb=" + unixtime; + model.setPreview(preview); if(result.has("edge_servers")) { JSONArray edgeServers = result.getJSONArray("edge_servers"); model.setStreamUrl("https://" + edgeServers.getString(0) + "/cam/mp4:" + streamName + "_h264_aac_480p/playlist.m3u8"); } + models.add(model); + } else { + String name = result.getString("username"); + CamsodaModel model = (CamsodaModel) camsoda.createModel(name); - if(result.has("tsize")) { - long unixtime = System.currentTimeMillis() / 1000; - String tsize = result.getString("tsize"); - String preview = "https://thumbs-orig.camsoda.com/thumbs/" - + streamName + '/' + serverPrefix + '/' + tsize + '/' + unixtime + '/' + name + ".jpg?cb=" + unixtime; - model.setPreview(preview); + if(result.has("server_prefix")) { + String serverPrefix = result.getString("server_prefix"); + String streamName = result.getString("stream_name"); + model.setSortOrder(result.getFloat("sort_value")); + models.add(model); + if(result.has("status")) { + model.setOnlineState(result.getString("status")); + } + + if(result.has("edge_servers")) { + JSONArray edgeServers = result.getJSONArray("edge_servers"); + model.setStreamUrl("https://" + edgeServers.getString(0) + "/cam/mp4:" + streamName + "_h264_aac_480p/playlist.m3u8"); + } + + if(result.has("tsize")) { + long unixtime = System.currentTimeMillis() / 1000; + String tsize = result.getString("tsize"); + String preview = "https://thumbs-orig.camsoda.com/thumbs/" + + streamName + '/' + serverPrefix + '/' + tsize + '/' + unixtime + '/' + name + ".jpg?cb=" + unixtime; + model.setPreview(preview); + } } - } } + return models.stream() + .sorted((m1,m2) -> (int)(m2.getSortOrder() - m1.getSortOrder())) + .skip( (page-1) * modelsPerPage) + .limit(modelsPerPage) + .collect(Collectors.toList()); + } else { + return Collections.emptyList(); } - return models.stream() - .sorted((m1,m2) -> (int)(m2.getSortOrder() - m1.getSortOrder())) - .skip( (page-1) * modelsPerPage) - .limit(modelsPerPage) - .collect(Collectors.toList()); } else { - response.close(); - return Collections.emptyList(); + throw new HttpException(response.code(), response.message()); } - } else { - int code = response.code(); - response.close(); - throw new IOException("HTTP status " + code); } } } diff --git a/src/main/java/ctbrec/sites/chaturbate/Chaturbate.java b/src/main/java/ctbrec/sites/chaturbate/Chaturbate.java index 4c2dfd13..862b064c 100644 --- a/src/main/java/ctbrec/sites/chaturbate/Chaturbate.java +++ b/src/main/java/ctbrec/sites/chaturbate/Chaturbate.java @@ -27,6 +27,7 @@ import com.squareup.moshi.Moshi; import ctbrec.Config; import ctbrec.Model; import ctbrec.io.HttpClient; +import ctbrec.io.HttpException; import ctbrec.recorder.Recorder; import ctbrec.sites.AbstractSite; import ctbrec.sites.ConfigUI; @@ -207,7 +208,7 @@ public class Chaturbate extends AbstractSite { return streamInfoCache.get(modelName); } - StreamInfo loadStreamInfo(String modelName) throws IOException, InterruptedException { + StreamInfo loadStreamInfo(String modelName) throws HttpException, IOException, InterruptedException { throttleRequests(); RequestBody body = new FormBody.Builder() .add("room_slug", modelName) @@ -231,7 +232,7 @@ public class Chaturbate extends AbstractSite { } else { int code = response.code(); String message = response.message(); - throw new IOException("Server responded with " + code + " - " + message + " headers: [" + response.headers() + "]"); + throw new HttpException(code, message); } } finally { response.close(); diff --git a/src/main/java/ctbrec/sites/mfc/FriendsUpdateService.java b/src/main/java/ctbrec/sites/mfc/FriendsUpdateService.java index 5b6aa165..08ac013c 100644 --- a/src/main/java/ctbrec/sites/mfc/FriendsUpdateService.java +++ b/src/main/java/ctbrec/sites/mfc/FriendsUpdateService.java @@ -47,36 +47,36 @@ public class FriendsUpdateService extends PaginatedScheduledService { .url(url) .header("Referer", myFreeCams.getBaseUrl()) .build(); - Response resp = myFreeCams.getHttpClient().execute(req, true); - if(resp.isSuccessful()) { - String body = resp.body().string().substring(4); - try { - JSONObject json = new JSONObject(body); - for (String key : json.keySet()) { - int uid = Integer.parseInt(key); - MyFreeCamsModel model = MyFreeCamsClient.getInstance().getModel(uid); - if(model == null) { - JSONObject modelObject = json.getJSONObject(key); - String name = modelObject.getString("u"); - model = myFreeCams.createModel(name); - SessionState st = new SessionState(); - st.setM(new ctbrec.sites.mfc.Model()); - st.getM().setCamscore(0.0); - st.setU(new User()); - st.setUid(uid); - st.setLv(modelObject.getInt("lv")); - st.setVs(127); + try(Response resp = myFreeCams.getHttpClient().execute(req, true)) { + if(resp.isSuccessful()) { + String body = resp.body().string().substring(4); + try { + JSONObject json = new JSONObject(body); + for (String key : json.keySet()) { + int uid = Integer.parseInt(key); + MyFreeCamsModel model = MyFreeCamsClient.getInstance().getModel(uid); + if(model == null) { + JSONObject modelObject = json.getJSONObject(key); + String name = modelObject.getString("u"); + model = myFreeCams.createModel(name); + SessionState st = new SessionState(); + st.setM(new ctbrec.sites.mfc.Model()); + st.getM().setCamscore(0.0); + st.setU(new User()); + st.setUid(uid); + st.setLv(modelObject.getInt("lv")); + st.setVs(127); - model.update(st, myFreeCams.getClient().getStreamUrl(st)); + model.update(st, myFreeCams.getClient().getStreamUrl(st)); + } + models.add(model); } - models.add(model); + } catch(Exception e) { + LOG.info("Exception getting friends list. Response was: {}", body); } - } catch(Exception e) { - LOG.info("Exception getting friends list. Response was: {}", body); + } else { + LOG.error("Couldn't load friends list {} {}", resp.code(), resp.message()); } - } else { - LOG.error("Couldn't load friends list {} {}", resp.code(), resp.message()); - resp.close(); } boolean filterOnline = mode == Mode.ONLINE; return models.stream() diff --git a/src/main/java/ctbrec/sites/mfc/MyFreeCams.java b/src/main/java/ctbrec/sites/mfc/MyFreeCams.java index 3c9cc2d4..56fc5de4 100644 --- a/src/main/java/ctbrec/sites/mfc/MyFreeCams.java +++ b/src/main/java/ctbrec/sites/mfc/MyFreeCams.java @@ -6,6 +6,7 @@ import org.jsoup.select.Elements; import ctbrec.Config; import ctbrec.Model; +import ctbrec.io.HttpException; import ctbrec.recorder.Recorder; import ctbrec.sites.AbstractSite; import ctbrec.sites.ConfigUI; @@ -74,15 +75,15 @@ public class MyFreeCams extends AbstractSite { @Override public Integer getTokenBalance() throws IOException { Request req = new Request.Builder().url(BASE_URI + "/php/account.php?request=status").build(); - Response resp = getHttpClient().execute(req, true); - if(resp.isSuccessful()) { - String content = resp.body().string(); - Elements tags = HtmlParser.getTags(content, "div.content > p > b"); - String tokens = tags.get(2).text(); - return Integer.parseInt(tokens); - } else { - resp.close(); - throw new IOException(resp.code() + " " + resp.message()); + try(Response response = getHttpClient().execute(req, true)) { + if(response.isSuccessful()) { + String content = response.body().string(); + Elements tags = HtmlParser.getTags(content, "div.content > p > b"); + String tokens = tags.get(2).text(); + return Integer.parseInt(tokens); + } else { + throw new HttpException(response.code(), response.message()); + } } } diff --git a/src/main/java/ctbrec/sites/mfc/MyFreeCamsClient.java b/src/main/java/ctbrec/sites/mfc/MyFreeCamsClient.java index 6af82a39..e05004af 100644 --- a/src/main/java/ctbrec/sites/mfc/MyFreeCamsClient.java +++ b/src/main/java/ctbrec/sites/mfc/MyFreeCamsClient.java @@ -282,10 +282,10 @@ public class MyFreeCamsClient { String url = base + "?respkey="+respkey+"&opts="+opts+"&serv="+serv+"&type="+type; Request req = new Request.Builder().url(url).build(); LOG.trace("Requesting EXTDATA {}", url); - Response resp = mfc.getHttpClient().execute(req); - - if(resp.isSuccessful()) { - parseExtDataSessionStates(resp.body().string()); + try(Response resp = mfc.getHttpClient().execute(req)) { + if(resp.isSuccessful()) { + parseExtDataSessionStates(resp.body().string()); + } } } catch(Exception e) { LOG.warn("Couldn't request EXTDATA", e); diff --git a/src/main/java/ctbrec/sites/mfc/MyFreeCamsHttpClient.java b/src/main/java/ctbrec/sites/mfc/MyFreeCamsHttpClient.java index 62c6229c..7924f5d4 100644 --- a/src/main/java/ctbrec/sites/mfc/MyFreeCamsHttpClient.java +++ b/src/main/java/ctbrec/sites/mfc/MyFreeCamsHttpClient.java @@ -11,6 +11,7 @@ import org.slf4j.LoggerFactory; import ctbrec.Config; import ctbrec.io.HttpClient; +import ctbrec.io.HttpException; import ctbrec.ui.HtmlParser; import okhttp3.Cookie; import okhttp3.CookieJar; @@ -75,20 +76,20 @@ public class MyFreeCamsHttpClient extends HttpClient { private boolean checkLogin() throws IOException { Request req = new Request.Builder().url(MyFreeCams.BASE_URI + "/php/account.php?request=status").build(); - Response resp = execute(req); - if(resp.isSuccessful()) { - String content = resp.body().string(); - try { - Elements tags = HtmlParser.getTags(content, "div.content > p > b"); - tags.get(2).text(); - return true; - } catch(Exception e) { - LOG.debug("Token tag not found. Login failed"); - return false; + try(Response response = execute(req)) { + if(response.isSuccessful()) { + String content = response.body().string(); + try { + Elements tags = HtmlParser.getTags(content, "div.content > p > b"); + tags.get(2).text(); + return true; + } catch(Exception e) { + LOG.debug("Token tag not found. Login failed"); + return false; + } + } else { + throw new HttpException(response.code(), response.message()); } - } else { - resp.close(); - throw new IOException(resp.code() + " " + resp.message()); } } diff --git a/src/main/java/ctbrec/sites/mfc/MyFreeCamsModel.java b/src/main/java/ctbrec/sites/mfc/MyFreeCamsModel.java index cc1f0e65..6378ce99 100644 --- a/src/main/java/ctbrec/sites/mfc/MyFreeCamsModel.java +++ b/src/main/java/ctbrec/sites/mfc/MyFreeCamsModel.java @@ -27,6 +27,7 @@ import com.squareup.moshi.JsonReader; import com.squareup.moshi.JsonWriter; import ctbrec.AbstractModel; +import ctbrec.io.HttpException; import ctbrec.recorder.download.StreamSource; import ctbrec.sites.Site; import ctbrec.ui.HtmlParser; @@ -104,8 +105,7 @@ public class MyFreeCamsModel extends AbstractModel { } LOG.trace("Loading master playlist {}", hlsUrl); Request req = new Request.Builder().url(hlsUrl).build(); - Response response = site.getHttpClient().execute(req); - try { + try(Response response = site.getHttpClient().execute(req)) { if(response.isSuccessful()) { InputStream inputStream = response.body().byteStream(); PlaylistParser parser = new PlaylistParser(inputStream, Format.EXT_M3U, Encoding.UTF_8); @@ -113,10 +113,8 @@ public class MyFreeCamsModel extends AbstractModel { MasterPlaylist master = playlist.getMasterPlaylist(); return master; } else { - throw new IOException(response.code() + " " + response.message()); + throw new HttpException(response.code(), response.message()); } - } finally { - response.close(); } } @@ -130,40 +128,40 @@ public class MyFreeCamsModel extends AbstractModel { String tipUrl = MyFreeCams.BASE_URI + "/php/tip.php"; String initUrl = tipUrl + "?request=tip&username="+getName()+"&broadcaster_id="+getUid(); Request req = new Request.Builder().url(initUrl).build(); - Response resp = site.getHttpClient().execute(req); - if(resp.isSuccessful()) { - String page = resp.body().string(); - Element hiddenInput = HtmlParser.getTag(page, "input[name=token]"); - String token = hiddenInput.attr("value"); - if (!Objects.equals(System.getenv("CTBREC_DEV"), "1")) { - RequestBody body = new FormBody.Builder() - .add("token", token) - .add("broadcaster_id", Integer.toString(uid)) - .add("tip_value", Integer.toString(tokens)) - .add("submit_tip", "1") - .add("anonymous", "") - .add("public", "1") - .add("public_comment", "1") - .add("hide_amount", "0") - .add("silent", "") - .add("comment", "") - .add("mode", "") - .add("submit", " Confirm & Close Window") - .build(); - req = new Request.Builder() - .url(tipUrl) - .post(body) - .addHeader("Referer", initUrl) - .build(); - try(Response response = site.getHttpClient().execute(req, true)) { - if(!response.isSuccessful()) { - throw new IOException(response.code() + " " + response.message()); + try(Response resp = site.getHttpClient().execute(req)) { + if(resp.isSuccessful()) { + String page = resp.body().string(); + Element hiddenInput = HtmlParser.getTag(page, "input[name=token]"); + String token = hiddenInput.attr("value"); + if (!Objects.equals(System.getenv("CTBREC_DEV"), "1")) { + RequestBody body = new FormBody.Builder() + .add("token", token) + .add("broadcaster_id", Integer.toString(uid)) + .add("tip_value", Integer.toString(tokens)) + .add("submit_tip", "1") + .add("anonymous", "") + .add("public", "1") + .add("public_comment", "1") + .add("hide_amount", "0") + .add("silent", "") + .add("comment", "") + .add("mode", "") + .add("submit", " Confirm & Close Window") + .build(); + req = new Request.Builder() + .url(tipUrl) + .post(body) + .addHeader("Referer", initUrl) + .build(); + try(Response response = site.getHttpClient().execute(req, true)) { + if(!response.isSuccessful()) { + throw new HttpException(response.code(), response.message()); + } } } + } else { + throw new HttpException(resp.code(), resp.message()); } - } else { - resp.close(); - throw new IOException(resp.code() + " " + resp.message()); } }