package ctbrec.sites.streamate; import static ctbrec.io.HttpConstants.*; import java.io.IOException; import java.util.Collections; import java.util.Locale; import java.util.NoSuchElementException; import java.util.UUID; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ctbrec.Config; import ctbrec.io.HttpClient; import ctbrec.io.HttpException; import okhttp3.Cookie; import okhttp3.HttpUrl; import okhttp3.MediaType; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; public class StreamateHttpClient extends HttpClient { private static final String SAKEY_KEY = "sakey"; private static final Logger LOG = LoggerFactory.getLogger(StreamateHttpClient.class); private Long userId; private String saKey = ""; private String userNickname = ""; private String xsrfToken = null; public StreamateHttpClient() { super("streamate"); // this cookie is needed for the search Cookie searchCookie = new Cookie.Builder() .domain("streamate.com") .name("Xld_rct") .value("1") .build(); getCookieJar().saveFromResponse(HttpUrl.parse(Streamate.BASE_URL), Collections.singletonList(searchCookie)); // try to load sakey from cookie try { Cookie cookie = getCookieJar().getCookie(HttpUrl.parse("https://www.streamate.com"), SAKEY_KEY); saKey = cookie.value(); } catch (NoSuchElementException e) { // ignore } loadXsrfToken(); } private void loadXsrfToken() { // do a first request to get cookies and stuff Request req = new Request.Builder() // .url(Streamate.BASE_URL + "/initialData.js") // .header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent) // .header(COOKIE, "smtid="+UUID.randomUUID().toString()+"; Xld_rct=1;") // .header(REFERER, Streamate.BASE_URL) .build(); try (Response resp = execute(req)) { if (resp.code() == 200) { LOG.info("Initial request was fine, Extracting XSRF token"); Matcher m = Pattern.compile("\"xsrfToken\":\"(.*?)\"").matcher(resp.body().string()); if (m.find()) { xsrfToken = m.group(1); } } else { throw new HttpException(resp.code(), resp.message()); } } catch (IOException e) { LOG.error("Initial request failed", e); } } @Override public synchronized boolean login() throws IOException { if(loggedIn) { return true; } boolean cookiesWorked = checkLoginSuccess(); if(cookiesWorked) { loggedIn = true; LOG.debug("Logged in with cookies"); return true; } loggedIn = loginWithoutCookies(); return loggedIn; } private synchronized boolean loginWithoutCookies() throws IOException { JSONObject loginRequest = new JSONObject(); loginRequest.put("allowLoginRedirection", true); loginRequest.put("email", Config.getInstance().getSettings().streamateUsername); loginRequest.put("password", Config.getInstance().getSettings().streamatePassword); loginRequest.put("referrerId", 0); loginRequest.put("siteId", 1); loginRequest.put("siteType", "premium"); loginRequest.put("tzOffsetMinutes", 0); RequestBody body = RequestBody.create(MediaType.parse("application/json"), loginRequest.toString()); Request login = newRequestBuilder() .url(Streamate.BASE_URL + "/api/member/login") .post(body) .build(); try (Response response = client.newCall(login).execute()) { String content = response.body().string(); if(response.isSuccessful()) { JSONObject json = new JSONObject(content); //LOG.debug(json.toString(2)); loggedIn = json.has(SAKEY_KEY); saKey = json.optString(SAKEY_KEY); JSONObject account = json.getJSONObject("account"); userId = account.getLong("userid"); userNickname = account.getString("nickname"); } else { throw new IOException("Login failed: " + response.code() + " " + response.message()); } } return loggedIn; } public Request.Builder newRequestBuilder() { return new Request.Builder() // @formatter:off .header(USER_AGENT, Config.getInstance().getSettings().httpUserAgent) .header(ACCEPT, MIMETYPE_APPLICATION_JSON) .header(ACCEPT_LANGUAGE, Locale.ENGLISH.getLanguage()) .header(REFERER, Streamate.BASE_URL) .header(X_REQUESTED_WITH, XML_HTTP_REQUEST) .header("X-XSRF-TOKEN", getXsrfToken()); // @formatter:on } /** * Check, if the login worked by loading the favorites */ public boolean checkLoginSuccess() { String url = Streamate.BASE_URL + "/api/search/v1/favorites?host=streamate.com&domain=streamate.com"; url = url + "&page_number=1&results_per_page=48&sakey=" + saKey + "&userid=" + userId; Request request = newRequestBuilder().url(url).build(); try (Response response = execute(request)) { if (response.isSuccessful()) { String content = response.body().string(); JSONObject json = new JSONObject(content); return json.optString("status").equals("SM_OK"); } else { return false; } } catch (Exception e) { return false; } } public String getSaKey() { return saKey; } public Long getUserId() throws IOException { if(userId == null) { loginWithoutCookies(); } return userId; } public String getUserNickname() { return userNickname; } public String getXsrfToken() { return xsrfToken; } }