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