/// <summary> /// Parse a response and return occured errors /// </summary> public RequestReport HandleResponse(ResponseEx response) { RequestReport result = null; // get the HTTP status code var status = response.StatusHttp; // if success or 'no content' if ((status == HttpStatusCode.OK) || (status == HttpStatusCode.Created) || (status == HttpStatusCode.NoContent)) { // then do nothing, it's not an error } // if any other case else { // create a simple error report result = new RequestReport(status) { Code = "Api.Client.Response.Failure", Message = status.ToString() }; } return(result); }
private async Task DownloadModule(RpcData rpcData, string courseDirectory, int moduleCounter, Module module) { var moduleDirectory = CreateModuleDirectory(courseDirectory, moduleCounter, module.Title); var course = rpcData.Payload.Course; var clipCounter = 0; string referrer = $"https://{Properties.Settings.Default.SiteHostName}/player?course={course.Name}&author={module.Author}&name={module.Name}&clip={clipCounter - 1}&mode=live"; HttpHelper httpHelper = new HttpHelper { AcceptEncoding = string.Empty, AcceptHeader = AcceptHeader.All, ContentType = ContentType.AppJsonUtf8, Cookies = Cookies, Referrer = new Uri(referrer), UserAgent = _userAgent }; foreach (var clip in module.Clips) { ++clipCounter; var postJson = BuildViewclipPostDataJson(rpcData, moduleCounter, clipCounter); var fileName = GetFullFileNameWithoutExtension(clipCounter, moduleDirectory, clip); if (!File.Exists($"{fileName}.{Properties.Settings.Default.ClipExtensionMp4}")) { ResponseEx viewclipResonse = await httpHelper.SendRequest(HttpMethod.Post, new Uri(Properties.Settings.Default.ViewClipUrl), postJson, Properties.Settings.Default.RetryOnRequestFailureCount, _token); if (viewclipResonse.Content == "Unauthorized") { throw new UnauthorizedException(Properties.Resources.CheckYourSubscription); } var clipFile = Newtonsoft.Json.JsonConvert.DeserializeObject <ClipFile>(viewclipResonse.Content); if (rpcData.Payload.Course.CourseHasCaptions) { string unformattedSubtitlesJson = await _subtitleService.DownloadAsync(httpHelper, module.Author, clipCounter - 1, module.Name, _token); Caption[] unformattedSubtitles = Newtonsoft.Json.JsonConvert.DeserializeObject <Caption[]>(unformattedSubtitlesJson); IList <SrtRecord> formattedSubtitles = GetFormattedSubtitles(unformattedSubtitles, clip.Duration); _subtitleService.Write($"{fileName}.{Properties.Settings.Default.SubtitilesExtensionMp4}", formattedSubtitles); } await DownloadClip(new Uri(clipFile.Urls[1].Url), fileName, clipCounter, rpcData.Payload.Course.Modules.Sum(m => m.Clips.Length)); } } }
public async Task <ResponseEx> SendRequest(HttpMethod method, Uri url, string postData, CancellationToken cancellationToken) { try { var responseEx = new ResponseEx { Content = string.Empty, ContentLength = 0 }; var requestMessage = GetHttpRequestMessage(method, postData); var client = GetHttpClient(url, UserAgent); if (client == null) { return(null); } using (var response = await client.SendAsync(requestMessage, cancellationToken)) using (var responseStream = await response.Content.ReadAsStreamAsync()) { responseEx.ResponseMessage = response; var contentLength = 0; if (response.Content.Headers.TryGetValues("Content-Length", out IEnumerable <string> contentLengthValues)) { contentLength = Convert.ToInt32(contentLengthValues.ElementAt(0)); } if (response.StatusCode == HttpStatusCode.Redirect) { if (response.Headers.TryGetValues("Set-Cookie", out IEnumerable <string> setCookieValues)) { responseEx.Cookies = string.Join(";", setCookieValues); } if (response.Headers.TryGetValues("Location", out IEnumerable <string> locationValues)) { responseEx.RedirectUrl = locationValues.First(); } } else { using (var reader = new StreamReader(responseStream, Encoding.UTF8)) { responseEx.Content = reader.ReadToEnd(); responseEx.ContentLength = contentLength; } } } return(responseEx); } catch (HttpRequestException exc) { #if DEBUG System.Diagnostics.Debug.Write(exc.ToString()); #endif return(null); } }
public async Task <string> DownloadAsync(HttpHelper httpHelper, string clipId, CancellationToken token) { string url = $"https://app.pluralsight.com/transcript/api/v1/caption/json/{clipId}/en"; ResponseEx response = await httpHelper.SendRequest(HttpMethod.Get, new Uri(url), null, Properties.Settings.Default.RetryOnRequestFailureCount, token); return(response.Content); }
public async Task <string> DownloadAsync(HttpHelper httpHelper, string authorId, int partNumber, string moduleName, CancellationToken token) { string postData = BuildSubtitlePostDataJson(authorId, partNumber, moduleName); ResponseEx response = await httpHelper.SendRequest(HttpMethod.Post, new Uri(Properties.Settings.Default.SubtitlesUrl), postData, Properties.Settings.Default.RetryOnRequestFailureCount, token); return(response.Content); }
private LoginResult GetLoginResult(ResponseEx loginResponse) { LoginResult loginResult = new LoginResult(); if (IsLoggedIn(loginResponse.Content, out var userData)) { loginResult.Status = LoginStatus.LoggedIn; loginResult.DataJson = userData; loginResult.Cookies = _cookies; } else { loginResult.Status = LoginStatus.Failed; } return(loginResult); }
private async Task <CourseExtraInfo> GetCourseExtraInfo(string productId, CancellationToken token) { HttpHelper httpHelper = new HttpHelper { AcceptHeader = AcceptHeader.JsonTextPlain, AcceptEncoding = string.Empty, ContentType = ContentType.AppJsonUtf8, Cookies = Cookies, Referrer = new Uri("https://" + Settings.Default.SiteHostName), UserAgent = _userAgent }; string graphQlRequest = GraphQlHelper.GetCourseExtraInfoRequest(productId); ResponseEx response = await httpHelper.SendRequest(HttpMethod.Post, new Uri("https://" + Settings.Default.SiteHostName + "/player/api/graphql"), graphQlRequest, Settings.Default.RetryOnRequestFailureCount, token); return(JsonConvert.DeserializeObject <CourseExtraInfo>(response.Content)); }
/// <summary> /// Parse a response and return occured errors /// </summary> public RequestReport HandleResponse <TContent>(out TContent content, ResponseEx response) where TContent : class { RequestReport result = null; content = null; // if we have a response if (response != null) { // get the HTTP status code var status = response.StatusHttp; // if we have a body if (response.HasBody) { // if succeeded if ((status == HttpStatusCode.OK) || (status == HttpStatusCode.Created)) { // deserialize content = response.GetBodyAsJson <TContent>(); // if parsing failed if (content == null) { // wrap in an error report result = new RequestReport(status) { Code = "Api.Client.Response.ParsingFailed.Content", Message = string.Format("Could not parse response body after a success [{0}]", response.GetBodyAsString()) }; } } // if failed else { // deserialize an error result = response.GetBodyAsJson <RequestReport>(); // if parsing succeeded if (result != null) { // update the status result.StatusCode = (int)status; } // if failed else { // wrap in an error report result = new RequestReport(status) { Code = "Api.Client.Response.ParsingFailed.Error", Message = string.Format("Could not parse response body after a failure [{0}]", response.GetBodyAsString()) }; } } } // if no body in the response else { // if it's an error if (status >= HttpStatusCode.BadRequest) { // create a simple error report result = new RequestReport(status) { Code = "Api.Client.Response.Failure", Message = status.ToString() }; } } } return(result); }
/// <summary> /// Manage failures for given response /// </summary> private static void ManageFailures(ResponseEx response) { // if we got a response if(response != null) { // if we have a failure if(!response.IsSuccessful) { // get request url string requestUrl = response.UrlRequest; // if none specified if(string.IsNullOrEmpty(requestUrl)) // set default requestUrl = "(unspecified)"; // get response error message string errorMessage = response.MessageError; // if none specified if(string.IsNullOrEmpty(errorMessage)) // set default errorMessage = "(no message)"; // get response body as a string string responseBody = response.GetBodyAsString(); // if none if(string.IsNullOrEmpty(responseBody)) // set default responseBody = "(no response body)"; // throw an exception throw new ApplicationException(string.Format("LicenceManager error [Http status: {0} - {1}] [Url: {2}] [Error message: {3}] [Response body: {4}]", (int)response.StatusHttp, response.StatusHttp, requestUrl, errorMessage, responseBody)); } } // if no response else // throw an exception throw new ApplicationException("No response "); }
private async Task DownloadModule(Course course, string courseDirectory, int moduleCounter, Module module) { var moduleDirectory = CreateModuleDirectory(courseDirectory, moduleCounter, module.Title); var clipCounter = 0; string referrer = $"https://{Settings.Default.SiteHostName}/player?course={course.Id}&author={module.AuthorId}&name={module.ModuleId}&clip=0&mode=live"; HttpHelper httpHelper = new HttpHelper { AcceptEncoding = string.Empty, AcceptHeader = AcceptHeader.All, ContentType = ContentType.AppJsonUtf8, Cookies = Cookies, Referrer = new Uri(referrer), UserAgent = _userAgent }; string moduleInfoPayload = GraphQlHelper.GetModuleInfoRequest(course.Id); ResponseEx courseRpcResponse = await httpHelper.SendRequest(HttpMethod.Post, new Uri("https://" + Settings.Default.SiteHostName + "/player/api/graphql"), moduleInfoPayload, Settings.Default.RetryOnRequestFailureCount, _token); CourseRpcData courceRpcData = JsonConvert.DeserializeObject <CourseRpcData>(courseRpcResponse.Content); foreach (var clip in module.Clips) { ++clipCounter; var fileName = GetFullFileNameWithoutExtension(clipCounter, moduleDirectory, clip); if (!File.Exists($"{fileName}.{Settings.Default.ClipExtensionMp4}")) { httpHelper.Referrer = new Uri($"https://{Settings.Default.SiteHostName}/player?course={course.Id}&author={module.AuthorId}&name={module.ModuleId}&clip=0&mode=live"); string s = GraphQlHelper.GetClipsRequest(courceRpcData, module.Id.Split('|')[1], module.Id.Split('|')[2], clipCounter - 1); ResponseEx viewclipResponse = await httpHelper.SendRequest(HttpMethod.Post, new Uri("https://" + Settings.Default.SiteHostName + "/player/api/graphql"), s, Settings.Default.RetryOnRequestFailureCount, _token); if (viewclipResponse.Content == "Unauthorized") { throw new UnauthorizedException(Resources.CheckYourSubscription); } var clipData = JsonConvert.DeserializeObject <ClipData>(viewclipResponse.Content); if (course.HasTranscript) { string unformattedSubtitlesJson = await _subtitleService.DownloadAsync(httpHelper, clip.ClipId.ToString(), _token); Caption[] unformattedSubtitles = JsonConvert.DeserializeObject <Caption[]>(unformattedSubtitlesJson); if (unformattedSubtitles.Length > 0) { TimeSpan totalDurationTs = XmlConvert.ToTimeSpan(clip.Duration); IList <SrtRecord> formattedSubtitles = GetFormattedSubtitles(unformattedSubtitles, totalDurationTs); _subtitleService.Write($"{fileName}.{Settings.Default.SubtitilesExtensionMp4}", formattedSubtitles); } } await DownloadClip(clipData.Data.ViewClip.Urls[1].UrlUrl, fileName, clipCounter, course.Modules.Sum(m => m.Clips.Length)); } } }