diff --git a/client/src/main/java/ctbrec/ui/JavaFxModel.java b/client/src/main/java/ctbrec/ui/JavaFxModel.java index 99c4fcb6..e57cc45d 100644 --- a/client/src/main/java/ctbrec/ui/JavaFxModel.java +++ b/client/src/main/java/ctbrec/ui/JavaFxModel.java @@ -110,7 +110,7 @@ public class JavaFxModel implements Model { } @Override - public String getOnlineState(boolean failFast) throws IOException, ExecutionException { + public STATUS getOnlineState(boolean failFast) throws IOException, ExecutionException { return delegate.getOnlineState(failFast); } diff --git a/client/src/main/java/ctbrec/ui/ThumbCell.java b/client/src/main/java/ctbrec/ui/ThumbCell.java index 5e9bdb16..914f2916 100644 --- a/client/src/main/java/ctbrec/ui/ThumbCell.java +++ b/client/src/main/java/ctbrec/ui/ThumbCell.java @@ -192,10 +192,6 @@ public class ThumbCell extends StackPane { setThumbWidth(Config.getInstance().getSettings().thumbWidth); setRecording(recording); - if(Config.getInstance().getSettings().determineResolution) { - determineResolution(); - } - update(); } @@ -221,11 +217,13 @@ public class ThumbCell extends StackPane { int[] resolution = resolutionCache.getIfPresent(model); if(resolution != null) { - try { - updateResolutionTag(resolution); - } catch(Exception e) { - LOG.warn("Couldn't update resolution tag for model {}", model.getName(), e); - } + ThumbOverviewTab.threadPool.submit(() -> { + try { + updateResolutionTag(resolution); + } catch(Exception e) { + LOG.warn("Couldn't update resolution tag for model {}", model.getName(), e); + } + }); } else { ThumbOverviewTab.threadPool.submit(() -> { try { @@ -263,14 +261,14 @@ public class ThumbCell extends StackPane { private void updateResolutionTag(int[] resolution) throws IOException, ExecutionException, InterruptedException { String _res = "n/a"; Paint resolutionBackgroundColor = resolutionOnlineColor; - String state = model.getOnlineState(false); + String state = model.getOnlineState(false).toString(); if (model.isOnline()) { LOG.trace("Model resolution {} {}x{}", model.getName(), resolution[0], resolution[1]); LOG.trace("Resolution queue size: {}", ThumbOverviewTab.queue.size()); final int w = resolution[1]; _res = w > 0 ? w != Integer.MAX_VALUE ? Integer.toString(w) : "HD" : state; } else { - _res = model.getOnlineState(false); + _res = model.getOnlineState(false).toString(); resolutionBackgroundColor = resolutionOfflineColor; } final String resText = _res; diff --git a/client/src/main/java/ctbrec/ui/ThumbOverviewTab.java b/client/src/main/java/ctbrec/ui/ThumbOverviewTab.java index c12bc189..00d3fe77 100644 --- a/client/src/main/java/ctbrec/ui/ThumbOverviewTab.java +++ b/client/src/main/java/ctbrec/ui/ThumbOverviewTab.java @@ -340,7 +340,6 @@ public class ThumbOverviewTab extends Tab implements TabSelectionListener { } List models = updateService.getValue(); updateGrid(models); - } protected void updateGrid(List models) { diff --git a/client/src/main/java/ctbrec/ui/sites/bonga/BongaCamsUpdateService.java b/client/src/main/java/ctbrec/ui/sites/bonga/BongaCamsUpdateService.java index cd52462a..06b1824c 100644 --- a/client/src/main/java/ctbrec/ui/sites/bonga/BongaCamsUpdateService.java +++ b/client/src/main/java/ctbrec/ui/sites/bonga/BongaCamsUpdateService.java @@ -1,5 +1,7 @@ package ctbrec.ui.sites.bonga; +import static ctbrec.Model.STATUS.*; + import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -58,16 +60,30 @@ public class BongaCamsUpdateService extends PaginatedScheduledService { BongaCamsModel model = (BongaCamsModel) bongaCams.createModel(name); model.setUserId(m.getInt("user_id")); boolean away = m.optBoolean("is_away"); - boolean online = m.optBoolean("online") && !away; + boolean online = m.optBoolean("online"); model.setOnline(online); + if(online) { + model.setOnlineState(ONLINE); if(away) { - model.setOnlineState("away"); + model.setOnlineState(AWAY); } else { - model.setOnlineState(m.getString("room")); + switch(m.optString("room")) { + case "private": + case "fullprivate": + model.setOnlineState(PRIVATE); + break; + case "group": + case "public": + model.setOnlineState(ONLINE); + break; + default: + LOG.debug(m.optString("room")); + model.setOnlineState(ONLINE); + } } } else { - model.setOnlineState("offline"); + model.setOnlineState(OFFLINE); } model.setPreview("https:" + m.getString("thumb_image")); if(m.has("display_name")) { diff --git a/client/src/main/java/ctbrec/ui/sites/cam4/Cam4FollowedUpdateService.java b/client/src/main/java/ctbrec/ui/sites/cam4/Cam4FollowedUpdateService.java index 60047998..4b68232b 100644 --- a/client/src/main/java/ctbrec/ui/sites/cam4/Cam4FollowedUpdateService.java +++ b/client/src/main/java/ctbrec/ui/sites/cam4/Cam4FollowedUpdateService.java @@ -68,7 +68,7 @@ public class Cam4FollowedUpdateService extends PaginatedScheduledService { 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)); + model.setOnlineStateByShowType(parseOnlineState(cellHtml)); models.add(model); } return models.stream() diff --git a/client/src/main/java/ctbrec/ui/sites/camsoda/CamsodaFollowedUpdateService.java b/client/src/main/java/ctbrec/ui/sites/camsoda/CamsodaFollowedUpdateService.java index 4e92d25c..39935366 100644 --- a/client/src/main/java/ctbrec/ui/sites/camsoda/CamsodaFollowedUpdateService.java +++ b/client/src/main/java/ctbrec/ui/sites/camsoda/CamsodaFollowedUpdateService.java @@ -1,5 +1,7 @@ package ctbrec.ui.sites.camsoda; +import static ctbrec.Model.STATUS.*; + import java.io.IOException; import java.util.ArrayList; import java.util.Collections; @@ -47,7 +49,7 @@ public class CamsodaFollowedUpdateService extends PaginatedScheduledService { 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.setOnlineState(online ? ONLINE : OFFLINE); model.setPreview("https://md.camsoda.com/thumbs/" + model.getName() + ".jpg"); models.add(model); } diff --git a/client/src/main/java/ctbrec/ui/sites/camsoda/CamsodaUpdateService.java b/client/src/main/java/ctbrec/ui/sites/camsoda/CamsodaUpdateService.java index 4b035962..3e3ff047 100644 --- a/client/src/main/java/ctbrec/ui/sites/camsoda/CamsodaUpdateService.java +++ b/client/src/main/java/ctbrec/ui/sites/camsoda/CamsodaUpdateService.java @@ -89,7 +89,7 @@ public class CamsodaUpdateService extends PaginatedScheduledService { model.setSortOrder(result.getFloat("sort_value")); models.add(model); if(result.has("status")) { - model.setOnlineState(result.getString("status")); + model.setOnlineStateByStatus(result.getString("status")); } if(result.has("display_name")) { diff --git a/common/src/main/java/ctbrec/AbstractModel.java b/common/src/main/java/ctbrec/AbstractModel.java index 61238759..2c925369 100644 --- a/common/src/main/java/ctbrec/AbstractModel.java +++ b/common/src/main/java/ctbrec/AbstractModel.java @@ -21,6 +21,7 @@ public abstract class AbstractModel implements Model { private int streamUrlIndex = -1; private boolean suspended = false; protected Site site; + protected STATUS onlineState = STATUS.UNKNOWN; @Override public boolean isOnline() throws IOException, ExecutionException, InterruptedException { @@ -121,6 +122,15 @@ public abstract class AbstractModel implements Model { this.suspended = suspended; } + @Override + public STATUS getOnlineState(boolean failFast) throws IOException, ExecutionException { + return onlineState; + } + + public void setOnlineState(STATUS status) { + this.onlineState = status; + } + @Override public int hashCode() { final int prime = 31; diff --git a/common/src/main/java/ctbrec/Model.java b/common/src/main/java/ctbrec/Model.java index 81cf2497..7df65838 100644 --- a/common/src/main/java/ctbrec/Model.java +++ b/common/src/main/java/ctbrec/Model.java @@ -65,7 +65,7 @@ public interface Model { public boolean isOnline(boolean ignoreCache) throws IOException, ExecutionException, InterruptedException; - public String getOnlineState(boolean failFast) throws IOException, ExecutionException; + public STATUS getOnlineState(boolean failFast) throws IOException, ExecutionException; public List getStreamSources() throws IOException, ExecutionException, ParseException, PlaylistException; @@ -101,4 +101,6 @@ public interface Model { public void setSuspended(boolean suspended); + + } \ No newline at end of file diff --git a/common/src/main/java/ctbrec/sites/bonga/BongaCamsModel.java b/common/src/main/java/ctbrec/sites/bonga/BongaCamsModel.java index eaad5853..2391547c 100644 --- a/common/src/main/java/ctbrec/sites/bonga/BongaCamsModel.java +++ b/common/src/main/java/ctbrec/sites/bonga/BongaCamsModel.java @@ -36,7 +36,6 @@ public class BongaCamsModel extends AbstractModel { private static final transient Logger LOG = LoggerFactory.getLogger(BongaCamsModel.class); private int userId; - private String onlineState = "n/a"; private boolean online = false; private List streamSources = new ArrayList<>(); private int[] resolution; @@ -84,11 +83,11 @@ public class BongaCamsModel extends AbstractModel { } @Override - public String getOnlineState(boolean failFast) throws IOException, ExecutionException { + public STATUS getOnlineState(boolean failFast) throws IOException, ExecutionException { return onlineState; } - public void setOnlineState(String onlineState) { + public void setOnlineState(STATUS onlineState) { this.onlineState = onlineState; } diff --git a/common/src/main/java/ctbrec/sites/cam4/Cam4Model.java b/common/src/main/java/ctbrec/sites/cam4/Cam4Model.java index 9381b9ad..680b0d59 100644 --- a/common/src/main/java/ctbrec/sites/cam4/Cam4Model.java +++ b/common/src/main/java/ctbrec/sites/cam4/Cam4Model.java @@ -1,5 +1,7 @@ package ctbrec.sites.cam4; +import static ctbrec.Model.STATUS.*; + import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; @@ -39,22 +41,19 @@ public class Cam4Model extends AbstractModel { private static final transient Logger LOG = LoggerFactory.getLogger(Cam4Model.class); private String playlistUrl; - private String onlineState = "offline"; private int[] resolution = null; private boolean privateRoom = false; @Override public boolean isOnline(boolean ignoreCache) throws IOException, ExecutionException, InterruptedException { - if(ignoreCache || onlineState == null) { + if(ignoreCache || onlineState == UNKNOWN) { try { loadModelDetails(); } catch (ModelDetailsEmptyException e) { return false; } } - return (Objects.equals("NORMAL", onlineState) || Objects.equals("GROUP_SHOW_SELLING_TICKETS", onlineState)) - && StringUtil.isNotBlank(playlistUrl) - && !privateRoom; + return onlineState == ONLINE && StringUtil.isNotBlank(playlistUrl) && !privateRoom; } private void loadModelDetails() throws IOException, ModelDetailsEmptyException { @@ -65,13 +64,17 @@ public class Cam4Model extends AbstractModel { if(response.isSuccessful()) { JSONArray json = new JSONArray(response.body().string()); if(json.length() == 0) { - onlineState = "offline"; + onlineState = OFFLINE; throw new ModelDetailsEmptyException("Model details are empty"); } JSONObject details = json.getJSONObject(0); - onlineState = details.getString("showType"); + String showType = details.getString("showType"); + setOnlineStateByShowType(showType); playlistUrl = details.getString("hlsPreviewUrl"); privateRoom = details.getBoolean("privateRoom"); + if(privateRoom) { + onlineState = PRIVATE; + } if(details.has("resolution")) { String res = details.getString("resolution"); String[] tokens = res.split(":"); @@ -83,9 +86,42 @@ public class Cam4Model extends AbstractModel { } } + public void setOnlineStateByShowType(String showType) { + switch(showType) { + case "NORMAL": + case "GROUP_SHOW_SELLING_TICKETS": + onlineState = ONLINE; + break; + case "PRIVATE_SHOW": + onlineState = PRIVATE; + break; + case "GROUP_SHOW": + onlineState = GROUP; + break; + case "OFFLINE": + onlineState = OFFLINE; + break; + default: + LOG.debug("Unknown show type {}", showType); + onlineState = UNKNOWN; + } + + } + @Override - public String getOnlineState(boolean failFast) throws IOException, ExecutionException { - return onlineState; + public STATUS getOnlineState(boolean failFast) throws IOException, ExecutionException { + if(failFast) { + return onlineState; + } else { + if(onlineState == UNKNOWN) { + try { + loadModelDetails(); + } catch (ModelDetailsEmptyException e) { + LOG.warn("Couldn't load model details", e.getMessage()); + } + } + return onlineState; + } } private String getPlaylistUrl() throws IOException { @@ -152,7 +188,11 @@ public class Cam4Model extends AbstractModel { return new int[2]; } else { try { - loadModelDetails(); + if(onlineState != OFFLINE) { + loadModelDetails(); + } else { + resolution = new int[2]; + } } catch (Exception e) { throw new ExecutionException(e); } @@ -226,10 +266,6 @@ public class Cam4Model extends AbstractModel { this.playlistUrl = playlistUrl; } - public void setOnlineState(String onlineState) { - this.onlineState = onlineState; - } - public class ModelDetailsEmptyException extends Exception { public ModelDetailsEmptyException(String msg) { super(msg); diff --git a/common/src/main/java/ctbrec/sites/camsoda/CamsodaModel.java b/common/src/main/java/ctbrec/sites/camsoda/CamsodaModel.java index 3c938eb4..12421216 100644 --- a/common/src/main/java/ctbrec/sites/camsoda/CamsodaModel.java +++ b/common/src/main/java/ctbrec/sites/camsoda/CamsodaModel.java @@ -1,5 +1,7 @@ package ctbrec.sites.camsoda; +import static ctbrec.Model.STATUS.*; + import java.io.IOException; import java.io.InputStream; import java.util.Collections; @@ -36,7 +38,6 @@ public class CamsodaModel extends AbstractModel { private static final transient Logger LOG = LoggerFactory.getLogger(CamsodaModel.class); private String streamUrl; private List streamSources = null; - private String status = "n/a"; private float sortOrder = 0; int[] resolution = new int[2]; @@ -56,7 +57,8 @@ public class CamsodaModel extends AbstractModel { JSONObject result = new JSONObject(response.body().string()); if(result.getBoolean("status")) { JSONObject chat = result.getJSONObject("user").getJSONObject("chat"); - status = chat.getString("status"); + String status = chat.getString("status"); + setOnlineStateByStatus(status); if(chat.has("edge_servers")) { String edgeServer = chat.getJSONArray("edge_servers").getString(0); String streamName = chat.getString("stream_name"); @@ -71,30 +73,46 @@ public class CamsodaModel extends AbstractModel { } } + public void setOnlineStateByStatus(String status) { + switch(status) { + case "online": + onlineState = ONLINE; + break; + case "offline": + onlineState = OFFLINE; + break; + case "private": + onlineState = PRIVATE; + break; + case "limited": + onlineState = GROUP; + break; + default: + LOG.debug("Unknown show type {}", status); + onlineState = UNKNOWN; + } + } + @Override public boolean isOnline(boolean ignoreCache) throws IOException, ExecutionException, InterruptedException { - if(ignoreCache) { + if(ignoreCache || onlineState == UNKNOWN) { loadModel(); } - return Objects.equals(status, "online"); + return onlineState == ONLINE; } @Override - public String getOnlineState(boolean failFast) throws IOException, ExecutionException { + public STATUS getOnlineState(boolean failFast) throws IOException, ExecutionException { if(failFast) { - return status; + return onlineState; } else { - if(status.equals("n/a")) { + if(onlineState == UNKNOWN) { loadModel(); } - return status; + return onlineState; } } - public void setOnlineState(String state) { - this.status = state; - } - @Override public List getStreamSources() throws IOException, ExecutionException, ParseException, PlaylistException { String streamUrl = getStreamUrl(); diff --git a/common/src/main/java/ctbrec/sites/chaturbate/ChaturbateModel.java b/common/src/main/java/ctbrec/sites/chaturbate/ChaturbateModel.java index 5a6acce3..faad4fd8 100644 --- a/common/src/main/java/ctbrec/sites/chaturbate/ChaturbateModel.java +++ b/common/src/main/java/ctbrec/sites/chaturbate/ChaturbateModel.java @@ -1,5 +1,7 @@ package ctbrec.sites.chaturbate; +import static ctbrec.Model.STATUS.*; + import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -74,14 +76,46 @@ public class ChaturbateModel extends AbstractModel { getChaturbate().streamInfoCache.invalidate(getName()); } - public String getOnlineState() throws IOException, ExecutionException { + public STATUS getOnlineState() throws IOException, ExecutionException { return getOnlineState(false); } @Override - public String getOnlineState(boolean failFast) throws IOException, ExecutionException { - StreamInfo info = getChaturbate().streamInfoCache.getIfPresent(getName()); - return info != null ? info.room_status : "n/a"; + public STATUS getOnlineState(boolean failFast) throws IOException, ExecutionException { + if(failFast) { + StreamInfo info = getChaturbate().streamInfoCache.getIfPresent(getName()); + setOnlineStateByRoomStatus(info.room_status); + } else { + StreamInfo info = getChaturbate().streamInfoCache.get(getName()); + setOnlineStateByRoomStatus(info.room_status); + } + return onlineState; + } + + private void setOnlineStateByRoomStatus(String room_status) { + if(room_status != null) { + switch(room_status) { + case "public": + onlineState = ONLINE; + break; + case "offline": + onlineState = OFFLINE; + break; + case "private": + case "hidden": + onlineState = PRIVATE; + break; + case "away": + onlineState = AWAY; + break; + case "group": + onlineState = STATUS.GROUP; + break; + default: + LOG.debug("Unknown show type {}", room_status); + onlineState = STATUS.UNKNOWN; + } + } } public StreamInfo getStreamInfo() throws IOException, ExecutionException { diff --git a/common/src/main/java/ctbrec/sites/mfc/MyFreeCamsModel.java b/common/src/main/java/ctbrec/sites/mfc/MyFreeCamsModel.java index 5bb3d998..69e67bed 100644 --- a/common/src/main/java/ctbrec/sites/mfc/MyFreeCamsModel.java +++ b/common/src/main/java/ctbrec/sites/mfc/MyFreeCamsModel.java @@ -68,28 +68,26 @@ public class MyFreeCamsModel extends AbstractModel { } @Override - public String getOnlineState(boolean failFast) throws IOException, ExecutionException { - return state != null ? state.toString() : "offline"; + public STATUS getOnlineState(boolean failFast) throws IOException, ExecutionException { + switch(this.state) { + case ONLINE: + case RECORDING: + return ctbrec.Model.STATUS.ONLINE; + case AWAY: + return ctbrec.Model.STATUS.AWAY; + case PRIVATE: + return ctbrec.Model.STATUS.PRIVATE; + case GROUP_SHOW: + return ctbrec.Model.STATUS.GROUP; + case OFFLINE: + case CAMOFF: + return ctbrec.Model.STATUS.OFFLINE; + default: + LOG.debug("State {} is not mapped", this.state); + return ctbrec.Model.STATUS.UNKNOWN; + } } - // @Override - // public STATUS getOnlineState() { - // switch(this.state) { - // case ONLINE: - // case RECORDING: - // return ctbrec.Model.STATUS.ONLINE; - // case AWAY: - // return ctbrec.Model.STATUS.AWAY; - // case PRIVATE: - // return ctbrec.Model.STATUS.PRIVATE; - // case GROUP_SHOW: - // return ctbrec.Model.STATUS.GROUP; - // default: - // LOG.debug("State {} is not mapped", this.state); - // return ctbrec.Model.STATUS.UNKNOWN; - // } - // } - @Override public List getStreamSources() throws IOException, ExecutionException, ParseException, PlaylistException { MasterPlaylist masterPlaylist = getMasterPlaylist();