package ctbrec.ui.sites.camsoda; import static ctbrec.Model.State.*; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.NoSuchElementException; import java.util.Objects; import java.util.function.Predicate; import java.util.stream.Collectors; import org.json.JSONArray; import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ctbrec.Model; import ctbrec.StringUtil; import ctbrec.io.HttpException; import ctbrec.sites.camsoda.Camsoda; import ctbrec.sites.camsoda.CamsodaModel; import ctbrec.ui.SiteUiFactory; import ctbrec.ui.tabs.PaginatedScheduledService; import javafx.concurrent.Task; import okhttp3.Request; import okhttp3.Response; public class CamsodaUpdateService extends PaginatedScheduledService { private static final Logger LOG = LoggerFactory.getLogger(CamsodaUpdateService.class); private String url; private boolean loginRequired; private Camsoda camsoda; int modelsPerPage = 50; private Predicate filter; public CamsodaUpdateService(String url, boolean loginRequired, Camsoda camsoda, Predicate filter) { this.url = url; this.loginRequired = loginRequired; this.camsoda = camsoda; this.filter = filter; } @Override protected Task> createTask() { return new Task>() { @Override public List call() throws IOException { return loadOnlineModels().stream() .sorted((m1,m2) -> (int)(m2.getSortOrder() - m1.getSortOrder())) .filter(filter) .skip( (page-1) * modelsPerPage) .limit(modelsPerPage) .collect(Collectors.toList()); } }; } protected List loadOnlineModels() throws IOException { List models = new ArrayList<>(); if(loginRequired && StringUtil.isBlank(ctbrec.Config.getInstance().getSettings().camsodaUsername)) { return Collections.emptyList(); } else { LOG.debug("Fetching page {}", url); if(loginRequired) { SiteUiFactory.getUi(camsoda).login(); } Request request = new Request.Builder().url(url).build(); try (Response response = camsoda.getHttpClient().execute(request)) { if (response.isSuccessful()) { String body = response.body().string(); JSONObject json = new JSONObject(body); if (json.optBoolean("status")) { JSONArray template = json.getJSONArray("template"); JSONArray results = json.getJSONArray("results"); for (int i = 0; i < results.length(); i++) { JSONObject result = results.getJSONObject(i); try { CamsodaModel model; if (result.has("tpl")) { JSONArray tpl = result.getJSONArray("tpl"); String name = tpl.getString(getTemplateIndex(template, "username")); model = (CamsodaModel) camsoda.createModel(name); model.setDescription(tpl.getString(getTemplateIndex(template, "subject_html"))); model.setSortOrder(tpl.getFloat(getTemplateIndex(template, "sort_value"))); String preview = "https:" + tpl.getString(getTemplateIndex(template, "thumb")); model.setPreview(preview); String displayName = tpl.getString(getTemplateIndex(template, "display_name")); model.setDisplayName(displayName.replaceAll("[^a-zA-Z0-9]", "")); if (model.getDisplayName().isBlank()) { model.setDisplayName(name); } model.setNew(result.optBoolean("new")); model.setOnlineState(tpl.getString(getTemplateIndex(template, "stream_name")).isEmpty() ? OFFLINE : ONLINE); models.add(model); } else { String name = result.getString("username"); model = (CamsodaModel) camsoda.createModel(name); model.setSortOrder(result.getFloat("sort_value")); if (result.has("status")) { model.setOnlineStateByStatus(result.getString("status")); } if (result.has("display_name")) { model.setDisplayName(result.getString("display_name").replaceAll("[^a-zA-Z0-9]", "")); if (model.getDisplayName().isBlank()) { model.setDisplayName(name); } } if (result.has("thumb")) { String previewUrl = "https:" + result.getString("thumb"); model.setPreview(previewUrl); } model.setNew(result.optBoolean("new")); models.add(model); } } catch (Exception e) { LOG.warn("Couldn't parse one of the models: {}", result, e); } } return models; } else { LOG.debug("Response was not successful: {}", json); return Collections.emptyList(); } } else { throw new HttpException(response.code(), response.message()); } } } } private int getTemplateIndex(JSONArray template, String string) { for (int i = 0; i < template.length(); i++) { String s = template.getString(i); if(Objects.equals(s, string)) { return i; } } throw new NoSuchElementException(string + " not found in template: " + template.toString()); } public void setFilter(Predicate filter) { this.filter = filter; } }