forked from j62/ctbrec
1
0
Fork 0

Introduced new HttpException for unsuccessful HTTP responses

Instead of throwing an IOException with String message, use the new
HttpException. The exception handling code can then use the status
code to be more specific how to handle the exception.

Also: use try-with-resources for the okhttp response where possible
This commit is contained in:
0xboobface 2018-11-14 14:43:26 +01:00
parent 8e1aabc7b7
commit 5b8d65ab27
20 changed files with 430 additions and 399 deletions

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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<Recording> 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<Recording> 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);
}
}

View File

@ -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());
}
}
}

View File

@ -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());
// }
// }
// }

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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<Model> 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<Model> 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);
}
}
}

View File

@ -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");
}

View File

@ -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<Model> 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);
}
}
};

View File

@ -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;

View File

@ -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());
}
}
}

View File

@ -82,30 +82,30 @@ public class CamsodaShowsTab extends Tab implements TabSelectionListener {
protected List<ShowBox> 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<ShowBox> 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<ShowBox> 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();
}

View File

@ -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);
}
}
}

View File

@ -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();

View File

@ -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()

View File

@ -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());
}
}
}

View File

@ -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);

View File

@ -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());
}
}

View File

@ -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());
}
}