From 436272f5ed246d9bbf5749aba7f53a68f594b708 Mon Sep 17 00:00:00 2001 From: 0xb00bface <0xboobface@gmail.com> Date: Sat, 22 May 2021 09:41:19 +0200 Subject: [PATCH 1/3] Add basic support for Amateur.tv --- .../java/ctbrec/ui/CamrecApplication.java | 2 + .../main/java/ctbrec/ui/SiteUiFactory.java | 10 +- .../ui/sites/amateurtv/AmateurTvSiteUi.java | 34 ++++ .../sites/amateurtv/AmateurTvTabProvider.java | 52 ++++++ .../amateurtv/AmateurTvUpdateService.java | 84 ++++++++++ .../ctbrec/sites/amateurtv/AmateurTv.java | 132 +++++++++++++++ .../sites/amateurtv/AmateurTvHttpClient.java | 22 +++ .../sites/amateurtv/AmateurTvModel.java | 155 ++++++++++++++++++ .../ctbrec/recorder/server/HttpServer.java | 2 + 9 files changed, 492 insertions(+), 1 deletion(-) create mode 100644 client/src/main/java/ctbrec/ui/sites/amateurtv/AmateurTvSiteUi.java create mode 100644 client/src/main/java/ctbrec/ui/sites/amateurtv/AmateurTvTabProvider.java create mode 100644 client/src/main/java/ctbrec/ui/sites/amateurtv/AmateurTvUpdateService.java create mode 100644 common/src/main/java/ctbrec/sites/amateurtv/AmateurTv.java create mode 100644 common/src/main/java/ctbrec/sites/amateurtv/AmateurTvHttpClient.java create mode 100644 common/src/main/java/ctbrec/sites/amateurtv/AmateurTvModel.java diff --git a/client/src/main/java/ctbrec/ui/CamrecApplication.java b/client/src/main/java/ctbrec/ui/CamrecApplication.java index 91cc6f10..27ceef98 100644 --- a/client/src/main/java/ctbrec/ui/CamrecApplication.java +++ b/client/src/main/java/ctbrec/ui/CamrecApplication.java @@ -45,6 +45,7 @@ import ctbrec.recorder.OnlineMonitor; import ctbrec.recorder.Recorder; import ctbrec.recorder.RemoteRecorder; import ctbrec.sites.Site; +import ctbrec.sites.amateurtv.AmateurTv; import ctbrec.sites.bonga.BongaCams; import ctbrec.sites.cam4.Cam4; import ctbrec.sites.camsoda.Camsoda; @@ -154,6 +155,7 @@ public class CamrecApplication extends Application { } private void initSites() { + sites.add(new AmateurTv()); sites.add(new BongaCams()); sites.add(new Cam4()); sites.add(new Camsoda()); diff --git a/client/src/main/java/ctbrec/ui/SiteUiFactory.java b/client/src/main/java/ctbrec/ui/SiteUiFactory.java index 2e371467..2f0fa57b 100644 --- a/client/src/main/java/ctbrec/ui/SiteUiFactory.java +++ b/client/src/main/java/ctbrec/ui/SiteUiFactory.java @@ -1,6 +1,7 @@ package ctbrec.ui; import ctbrec.sites.Site; +import ctbrec.sites.amateurtv.AmateurTv; import ctbrec.sites.bonga.BongaCams; import ctbrec.sites.cam4.Cam4; import ctbrec.sites.camsoda.Camsoda; @@ -13,6 +14,7 @@ import ctbrec.sites.mfc.MyFreeCams; import ctbrec.sites.showup.Showup; import ctbrec.sites.streamate.Streamate; import ctbrec.sites.stripchat.Stripchat; +import ctbrec.ui.sites.amateurtv.AmateurTvSiteUi; import ctbrec.ui.sites.bonga.BongaCamsSiteUi; import ctbrec.ui.sites.cam4.Cam4SiteUi; import ctbrec.ui.sites.camsoda.CamsodaSiteUi; @@ -28,6 +30,7 @@ import ctbrec.ui.sites.stripchat.StripchatSiteUi; public class SiteUiFactory { + private static AmateurTvSiteUi amateurTvUi; private static BongaCamsSiteUi bongaSiteUi; private static Cam4SiteUi cam4SiteUi; private static CamsodaSiteUi camsodaSiteUi; @@ -44,7 +47,12 @@ public class SiteUiFactory { private SiteUiFactory () {} public static synchronized SiteUI getUi(Site site) { - if (site instanceof BongaCams) { + if (site instanceof AmateurTv) { + if (amateurTvUi == null) { + amateurTvUi = new AmateurTvSiteUi((AmateurTv) site); + } + return amateurTvUi; + } else if (site instanceof BongaCams) { if (bongaSiteUi == null) { bongaSiteUi = new BongaCamsSiteUi((BongaCams) site); } diff --git a/client/src/main/java/ctbrec/ui/sites/amateurtv/AmateurTvSiteUi.java b/client/src/main/java/ctbrec/ui/sites/amateurtv/AmateurTvSiteUi.java new file mode 100644 index 00000000..ddd1c6fa --- /dev/null +++ b/client/src/main/java/ctbrec/ui/sites/amateurtv/AmateurTvSiteUi.java @@ -0,0 +1,34 @@ +package ctbrec.ui.sites.amateurtv; + +import java.io.IOException; + +import ctbrec.sites.amateurtv.AmateurTv; +import ctbrec.ui.sites.AbstractSiteUi; +import ctbrec.ui.sites.ConfigUI; +import ctbrec.ui.tabs.TabProvider; + +public class AmateurTvSiteUi extends AbstractSiteUi { + + private final AmateurTvTabProvider tabProvider; + private final AmateurTv amateurTv; + + public AmateurTvSiteUi(AmateurTv amateurTv) { + this.amateurTv = amateurTv; + tabProvider = new AmateurTvTabProvider(amateurTv); + } + + @Override + public TabProvider getTabProvider() { + return tabProvider; + } + + @Override + public ConfigUI getConfigUI() { + return null; + } + + @Override + public synchronized boolean login() throws IOException { + return amateurTv.login(); + } +} diff --git a/client/src/main/java/ctbrec/ui/sites/amateurtv/AmateurTvTabProvider.java b/client/src/main/java/ctbrec/ui/sites/amateurtv/AmateurTvTabProvider.java new file mode 100644 index 00000000..7dff848e --- /dev/null +++ b/client/src/main/java/ctbrec/ui/sites/amateurtv/AmateurTvTabProvider.java @@ -0,0 +1,52 @@ +package ctbrec.ui.sites.amateurtv; + +import java.util.ArrayList; +import java.util.List; + +import ctbrec.recorder.Recorder; +import ctbrec.sites.amateurtv.AmateurTv; +import ctbrec.ui.tabs.PaginatedScheduledService; +import ctbrec.ui.tabs.TabProvider; +import ctbrec.ui.tabs.ThumbOverviewTab; +import javafx.scene.Scene; +import javafx.scene.control.Tab; + +public class AmateurTvTabProvider implements TabProvider { + + private AmateurTv amateurTv; + private Recorder recorder; + + public AmateurTvTabProvider(AmateurTv amateurTv) { + this.amateurTv = amateurTv; + this.recorder = amateurTv.getRecorder(); + } + + @Override + public List getTabs(Scene scene) { + List tabs = new ArrayList<>(); + + // female + String url = AmateurTv.baseUrl + "/v3/readmodel/cache/cams/W"; + var updateService = new AmateurTvUpdateService(amateurTv, url); + tabs.add(createTab("Female", updateService)); + + // male + url = AmateurTv.baseUrl + "/v3/readmodel/cache/cams/M"; + updateService = new AmateurTvUpdateService(amateurTv, url); + tabs.add(createTab("Male", updateService)); + + return tabs; + } + + private Tab createTab(String title, PaginatedScheduledService updateService) { + var tab = new ThumbOverviewTab(title, updateService, amateurTv); + tab.setRecorder(recorder); + return tab; + } + + @Override + public Tab getFollowedTab() { + return null; + } + +} diff --git a/client/src/main/java/ctbrec/ui/sites/amateurtv/AmateurTvUpdateService.java b/client/src/main/java/ctbrec/ui/sites/amateurtv/AmateurTvUpdateService.java new file mode 100644 index 00000000..8c5fccca --- /dev/null +++ b/client/src/main/java/ctbrec/ui/sites/amateurtv/AmateurTvUpdateService.java @@ -0,0 +1,84 @@ +package ctbrec.ui.sites.amateurtv; + +import static ctbrec.io.HttpConstants.*; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import org.json.JSONArray; +import org.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import ctbrec.Config; +import ctbrec.Model; +import ctbrec.sites.amateurtv.AmateurTv; +import ctbrec.sites.amateurtv.AmateurTvModel; +import ctbrec.ui.tabs.PaginatedScheduledService; +import javafx.concurrent.Task; +import okhttp3.Request; + +public class AmateurTvUpdateService extends PaginatedScheduledService { + + private static final Logger LOG = LoggerFactory.getLogger(AmateurTvUpdateService.class); + private static final int ITEMS_PER_PAGE = 50; + + private AmateurTv site; + private String url; + + public AmateurTvUpdateService(AmateurTv site, String url) { + this.site = site; + this.url = url; + } + + @Override + protected Task> createTask() { + return new Task>() { + @Override + public List call() throws IOException { + return loadModelList(); + } + + }; + } + + private List loadModelList() throws IOException { + int offset = page - 1; + String pageUrl = url + '/' + offset * ITEMS_PER_PAGE + '/' + ITEMS_PER_PAGE + "/es"; + LOG.debug("Fetching page {}", pageUrl); + var request = new Request.Builder() + .url(pageUrl) + .header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent) + .header(ACCEPT, MIMETYPE_APPLICATION_JSON) + .header(ACCEPT, Locale.ENGLISH.getLanguage()) + .header(REFERER, site.getBaseUrl()) + .build(); + try (var response = site.getHttpClient().execute(request)) { + if (response.isSuccessful()) { + var content = response.body().string(); + List models = new ArrayList<>(); + var json = new JSONObject(content); + var modelNodes = json.getJSONObject("cams").getJSONArray("nodes"); + parseModels(modelNodes, models); + return models; + } else { + int code = response.code(); + throw new IOException("HTTP status " + code); + } + } + } + + private void parseModels(JSONArray jsonModels, List models) { + for (var i = 0; i < jsonModels.length(); i++) { + var m = jsonModels.getJSONObject(i); + var user = m.getJSONObject("user"); + var name = user.optString("username"); + AmateurTvModel model = (AmateurTvModel) site.createModel(name); + model.setPreview(m.optString("imageURL")); + model.setDescription(m.optJSONObject("topic").optString("text")); + models.add(model); + } + } +} diff --git a/common/src/main/java/ctbrec/sites/amateurtv/AmateurTv.java b/common/src/main/java/ctbrec/sites/amateurtv/AmateurTv.java new file mode 100644 index 00000000..11bf2f63 --- /dev/null +++ b/common/src/main/java/ctbrec/sites/amateurtv/AmateurTv.java @@ -0,0 +1,132 @@ +package ctbrec.sites.amateurtv; + +import java.io.IOException; +import java.util.Collections; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import ctbrec.Model; +import ctbrec.io.HttpClient; +import ctbrec.sites.AbstractSite; + +public class AmateurTv extends AbstractSite { + + private static final Logger LOG = LoggerFactory.getLogger(AmateurTv.class); + + public static String baseUrl = "https://www.amateur.tv"; + + private AmateurTvHttpClient httpClient; + + + @Override + public void init() throws IOException { + // nothing to do + } + + @Override + public String getName() { + return "Amateur.tv"; + } + + @Override + public String getBaseUrl() { + return baseUrl; + } + + @Override + public Model createModel(String name) { + AmateurTvModel model = new AmateurTvModel(); + model.setName(name); + model.setUrl(baseUrl + '/' + name); + model.setDescription(""); + model.setSite(this); + return model; + } + + @Override + public Double getTokenBalance() throws IOException { + return Double.valueOf(0); + } + + @Override + public String getBuyTokensLink() { + return getAffiliateLink(); + } + + @Override + public synchronized boolean login() throws IOException { + return credentialsAvailable() && getHttpClient().login(); + } + + @Override + public HttpClient getHttpClient() { + if (httpClient == null) { + httpClient = new AmateurTvHttpClient(); + } + return httpClient; + } + + @Override + public void shutdown() { + if (httpClient != null) { + httpClient.shutdown(); + } + } + + @Override + public boolean supportsTips() { + return true; + } + + @Override + public boolean supportsFollow() { + return true; + } + + @Override + public boolean supportsSearch() { + return true; + } + + @Override + public boolean searchRequiresLogin() { + return true; + } + + @Override + public List search(String q) throws IOException, InterruptedException { + return Collections.emptyList(); + } + + @Override + public boolean isSiteForModel(Model m) { + return m instanceof AmateurTvModel; + } + + @Override + public boolean credentialsAvailable() { + //String username = Config.getInstance().getSettings().bongaUsername; + //return username != null && !username.trim().isEmpty(); + return false; + } + + @Override + public Model createModelFromUrl(String url) { + Matcher m = Pattern.compile("https?://.*?amateur.tv/.*").matcher(url); + if(m.matches()) { + String modelName = m.group(1); + return createModel(modelName); + } else { + return super.createModelFromUrl(url); + } + } + + @Override + public String getAffiliateLink() { + return baseUrl; + } +} diff --git a/common/src/main/java/ctbrec/sites/amateurtv/AmateurTvHttpClient.java b/common/src/main/java/ctbrec/sites/amateurtv/AmateurTvHttpClient.java new file mode 100644 index 00000000..74d23d4f --- /dev/null +++ b/common/src/main/java/ctbrec/sites/amateurtv/AmateurTvHttpClient.java @@ -0,0 +1,22 @@ +package ctbrec.sites.amateurtv; + +import java.io.IOException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import ctbrec.io.HttpClient; + +public class AmateurTvHttpClient extends HttpClient { + + private static final Logger LOG = LoggerFactory.getLogger(AmateurTvHttpClient.class); + + public AmateurTvHttpClient() { + super("amateurtv"); + } + + @Override + public boolean login() throws IOException { + return false; + } +} diff --git a/common/src/main/java/ctbrec/sites/amateurtv/AmateurTvModel.java b/common/src/main/java/ctbrec/sites/amateurtv/AmateurTvModel.java new file mode 100644 index 00000000..832caebf --- /dev/null +++ b/common/src/main/java/ctbrec/sites/amateurtv/AmateurTvModel.java @@ -0,0 +1,155 @@ +package ctbrec.sites.amateurtv; + +import static ctbrec.Model.State.*; +import static ctbrec.io.HttpConstants.*; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutionException; + +import javax.xml.bind.JAXBException; + +import org.json.JSONObject; +import org.jsoup.nodes.Element; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.iheartradio.m3u8.Encoding; +import com.iheartradio.m3u8.Format; +import com.iheartradio.m3u8.ParseException; +import com.iheartradio.m3u8.ParsingMode; +import com.iheartradio.m3u8.PlaylistException; +import com.iheartradio.m3u8.PlaylistParser; +import com.iheartradio.m3u8.data.MasterPlaylist; +import com.iheartradio.m3u8.data.Playlist; +import com.iheartradio.m3u8.data.PlaylistData; +import com.iheartradio.m3u8.data.StreamInfo; + +import ctbrec.AbstractModel; +import ctbrec.Config; +import ctbrec.io.HttpClient; +import ctbrec.io.HttpException; +import ctbrec.recorder.download.StreamSource; +import okhttp3.Request; +import okhttp3.Response; + +public class AmateurTvModel extends AbstractModel { + + private static final Logger LOG = LoggerFactory.getLogger(AmateurTvModel.class); + + private boolean online = false; + + @Override + public boolean isOnline(boolean ignoreCache) throws IOException, ExecutionException, InterruptedException { + if (ignoreCache) { + JSONObject json = getModelInfo(); + online = json.optString("status").equalsIgnoreCase("online"); + onlineState = online ? ONLINE : OFFLINE; + } + return online; + } + + @Override + public State getOnlineState(boolean failFast) throws IOException, ExecutionException { + if (failFast) { + return onlineState; + } else { + try { + isOnline(true); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + onlineState = OFFLINE; + } catch (IOException | ExecutionException e) { + onlineState = OFFLINE; + } + return onlineState; + } + } + + @Override + public List getStreamSources() throws IOException, ExecutionException, ParseException, PlaylistException, JAXBException { + List streamSources = new ArrayList<>(); + String streamUrl = getStreamUrl(); + Request req = new Request.Builder().url(streamUrl).build(); + 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, ParsingMode.LENIENT); + Playlist playlist = parser.parse(); + MasterPlaylist master = playlist.getMasterPlaylist(); + for (PlaylistData playlistData : master.getPlaylists()) { + StreamSource streamsource = new StreamSource(); + Element img = new Element("img"); + img.setBaseUri(streamUrl); + img.attr("src", playlistData.getUri()); + streamsource.mediaPlaylistUrl = img.absUrl("src"); + if (playlistData.hasStreamInfo()) { + StreamInfo info = playlistData.getStreamInfo(); + streamsource.bandwidth = info.getBandwidth(); + streamsource.width = info.hasResolution() ? info.getResolution().width : 0; + streamsource.height = info.hasResolution() ? info.getResolution().height : 0; + } else { + streamsource.bandwidth = 0; + streamsource.width = 0; + streamsource.height = 0; + } + streamSources.add(streamsource); + } + } else { + throw new HttpException(response.code(), response.message()); + } + } + return streamSources; + } + + private String getStreamUrl() throws IOException { + JSONObject json = getModelInfo(); + JSONObject videoTech = json.getJSONObject("videoTechnologies"); + return videoTech.getString("hlsV2"); + } + + @Override + public void invalidateCacheEntries() { + // nothing to do + } + + @Override + public void receiveTip(Double tokens) throws IOException { + // not supported + } + + @Override + public int[] getStreamResolution(boolean failFast) throws ExecutionException { + try { + return new int[] { getStreamSources().get(0).width, getStreamSources().get(0).height }; + } catch (Exception e) { + throw new ExecutionException(e); + } + } + + @Override + public boolean follow() throws IOException { + return false; + } + + @Override + public boolean unfollow() throws IOException { + return false; + } + + private JSONObject getModelInfo() throws IOException { + String url = AmateurTv.baseUrl + "/v3/readmodel/show/" + getName() + "/es"; + Request req = new Request.Builder().url(url) + .header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent) + .header(ACCEPT, MIMETYPE_APPLICATION_JSON) + .header(ACCEPT_LANGUAGE, "en") + .header(REFERER, getSite().getBaseUrl() + '/' + getName()) + .build(); + try (Response resp = site.getHttpClient().execute(req)) { + JSONObject json = new JSONObject(HttpClient.bodyToJsonObject(resp)); + return json; + } + } +} diff --git a/server/src/main/java/ctbrec/recorder/server/HttpServer.java b/server/src/main/java/ctbrec/recorder/server/HttpServer.java index f17f753b..252f1b82 100644 --- a/server/src/main/java/ctbrec/recorder/server/HttpServer.java +++ b/server/src/main/java/ctbrec/recorder/server/HttpServer.java @@ -65,6 +65,7 @@ import ctbrec.recorder.OnlineMonitor; import ctbrec.recorder.Recorder; import ctbrec.servlet.StaticFileServlet; import ctbrec.sites.Site; +import ctbrec.sites.amateurtv.AmateurTv; import ctbrec.sites.bonga.BongaCams; import ctbrec.sites.cam4.Cam4; import ctbrec.sites.camsoda.Camsoda; @@ -142,6 +143,7 @@ public class HttpServer { } private void createSites() { + sites.add(new AmateurTv()); sites.add(new BongaCams()); sites.add(new Cam4()); sites.add(new Camsoda()); From fc7bb1362c7bbd267e86b202799ac3be05ecd0c2 Mon Sep 17 00:00:00 2001 From: 0xb00bface <0xboobface@gmail.com> Date: Sun, 23 May 2021 16:55:31 +0200 Subject: [PATCH 2/3] Add more tabs for amateur.tv --- .../sites/amateurtv/AmateurTvTabProvider.java | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/client/src/main/java/ctbrec/ui/sites/amateurtv/AmateurTvTabProvider.java b/client/src/main/java/ctbrec/ui/sites/amateurtv/AmateurTvTabProvider.java index 7dff848e..44df2ac7 100644 --- a/client/src/main/java/ctbrec/ui/sites/amateurtv/AmateurTvTabProvider.java +++ b/client/src/main/java/ctbrec/ui/sites/amateurtv/AmateurTvTabProvider.java @@ -25,9 +25,14 @@ public class AmateurTvTabProvider implements TabProvider { public List getTabs(Scene scene) { List tabs = new ArrayList<>(); - // female - String url = AmateurTv.baseUrl + "/v3/readmodel/cache/cams/W"; + // all + var url = AmateurTv.baseUrl + "/v3/readmodel/cache/cams/A"; var updateService = new AmateurTvUpdateService(amateurTv, url); + tabs.add(createTab("All", updateService)); + + // female + url = AmateurTv.baseUrl + "/v3/readmodel/cache/cams/W"; + updateService = new AmateurTvUpdateService(amateurTv, url); tabs.add(createTab("Female", updateService)); // male @@ -35,6 +40,16 @@ public class AmateurTvTabProvider implements TabProvider { updateService = new AmateurTvUpdateService(amateurTv, url); tabs.add(createTab("Male", updateService)); + // couples + url = AmateurTv.baseUrl + "/v3/readmodel/cache/cams/C"; + updateService = new AmateurTvUpdateService(amateurTv, url); + tabs.add(createTab("Couples", updateService)); + + // trans + url = AmateurTv.baseUrl + "/v3/readmodel/cache/cams/T"; + updateService = new AmateurTvUpdateService(amateurTv, url); + tabs.add(createTab("Trans", updateService)); + return tabs; } From d44fc58bf2e393a23cbdd311e5a4cd62470b66ac Mon Sep 17 00:00:00 2001 From: 0xb00bface <0xboobface@gmail.com> Date: Sun, 23 May 2021 16:56:14 +0200 Subject: [PATCH 3/3] Fix display of resolution tag for amateur.tv --- .../src/main/java/ctbrec/ui/tabs/ThumbCell.java | 2 +- common/src/main/java/ctbrec/Model.java | 11 ++++++++++- .../java/ctbrec/sites/amateurtv/AmateurTv.java | 15 +++++---------- .../ctbrec/sites/amateurtv/AmateurTvModel.java | 8 ++------ 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/client/src/main/java/ctbrec/ui/tabs/ThumbCell.java b/client/src/main/java/ctbrec/ui/tabs/ThumbCell.java index 677cc3b7..7d4a994c 100644 --- a/client/src/main/java/ctbrec/ui/tabs/ThumbCell.java +++ b/client/src/main/java/ctbrec/ui/tabs/ThumbCell.java @@ -727,7 +727,7 @@ public class ThumbCell extends StackPane { try { return model.getStreamResolution(false); } catch (ExecutionException e) { - LOG.warn("Error loading stream resolution for model {}", model, e); + LOG.debug("Error loading stream resolution for model {}: {}", model, e.getLocalizedMessage()); return new int[2]; } } diff --git a/common/src/main/java/ctbrec/Model.java b/common/src/main/java/ctbrec/Model.java index 551ac5c4..0cb9ab1e 100644 --- a/common/src/main/java/ctbrec/Model.java +++ b/common/src/main/java/ctbrec/Model.java @@ -76,6 +76,15 @@ public interface Model extends Comparable, Serializable { public boolean isOnline() throws IOException, ExecutionException, InterruptedException; + /** + * + * @param failFast + * If set to true, the method returns immediately and might return false even if the model actually is online + * @return + * @throws IOException + * @throws ExecutionException + * @throws InterruptedException + */ public boolean isOnline(boolean ignoreCache) throws IOException, ExecutionException, InterruptedException; public State getOnlineState(boolean failFast) throws IOException, ExecutionException; @@ -98,7 +107,7 @@ public interface Model extends Comparable, Serializable { * Determines the stream resolution for this model * * @param failFast - * If set to true, the method returns emmediately, even if the resolution is unknown. If + * If set to true, the method returns immediately, even if the resolution is unknown. If * the resolution is unknown, the array contains 0,0 * * @return a tupel of width and height represented by an int[2] diff --git a/common/src/main/java/ctbrec/sites/amateurtv/AmateurTv.java b/common/src/main/java/ctbrec/sites/amateurtv/AmateurTv.java index 11bf2f63..16ae8612 100644 --- a/common/src/main/java/ctbrec/sites/amateurtv/AmateurTv.java +++ b/common/src/main/java/ctbrec/sites/amateurtv/AmateurTv.java @@ -6,17 +6,12 @@ import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import ctbrec.Model; import ctbrec.io.HttpClient; import ctbrec.sites.AbstractSite; public class AmateurTv extends AbstractSite { - private static final Logger LOG = LoggerFactory.getLogger(AmateurTv.class); - public static String baseUrl = "https://www.amateur.tv"; private AmateurTvHttpClient httpClient; @@ -79,22 +74,22 @@ public class AmateurTv extends AbstractSite { @Override public boolean supportsTips() { - return true; + return false; } @Override public boolean supportsFollow() { - return true; + return false; } @Override public boolean supportsSearch() { - return true; + return false; } @Override public boolean searchRequiresLogin() { - return true; + return false; } @Override @@ -116,7 +111,7 @@ public class AmateurTv extends AbstractSite { @Override public Model createModelFromUrl(String url) { - Matcher m = Pattern.compile("https?://.*?amateur.tv/.*").matcher(url); + Matcher m = Pattern.compile("https?://.*?amateur.tv/(.*)").matcher(url); if(m.matches()) { String modelName = m.group(1); return createModel(modelName); diff --git a/common/src/main/java/ctbrec/sites/amateurtv/AmateurTvModel.java b/common/src/main/java/ctbrec/sites/amateurtv/AmateurTvModel.java index 832caebf..7697516d 100644 --- a/common/src/main/java/ctbrec/sites/amateurtv/AmateurTvModel.java +++ b/common/src/main/java/ctbrec/sites/amateurtv/AmateurTvModel.java @@ -13,8 +13,6 @@ import javax.xml.bind.JAXBException; import org.json.JSONObject; import org.jsoup.nodes.Element; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import com.iheartradio.m3u8.Encoding; import com.iheartradio.m3u8.Format; @@ -37,8 +35,6 @@ import okhttp3.Response; public class AmateurTvModel extends AbstractModel { - private static final Logger LOG = LoggerFactory.getLogger(AmateurTvModel.class); - private boolean online = false; @Override @@ -53,11 +49,11 @@ public class AmateurTvModel extends AbstractModel { @Override public State getOnlineState(boolean failFast) throws IOException, ExecutionException { - if (failFast) { + if (failFast && onlineState != UNKNOWN) { return onlineState; } else { try { - isOnline(true); + onlineState = isOnline(true) ? ONLINE : OFFLINE; } catch (InterruptedException e) { Thread.currentThread().interrupt(); onlineState = OFFLINE;