/// <summary> /// Gets the images from the specified url. /// </summary> /// <param name="client"></param> /// <param name="url"></param> /// <returns></returns> public static async Task <ImageResponse> GetDiyidanImagesAsync(IDownloaderClient client, Uri url) { var u = DownloaderClient.RemoveQuery(url).ToString(); if (u.IsImagePath()) { return(ImageResponse.FromUrl(new Uri(u))); } var result = await client.GetHtmlAsync(() => client.GenerateReq(url)).CAF(); if (!result.IsSuccess) { return(ImageResponse.FromNotFound(url)); } var div = result.Value.DocumentNode.Descendants("div"); if (div.Any(x => x.GetAttributeValue("class", null) == "video_404_box")) { return(ImageResponse.FromAnimated(url)); } var content = div.SingleOrDefault(x => x.GetAttributeValue("class", "").CaseInsContains("user_post_content")); if (content == null) { return(ImageResponse.FromNotFound(url)); } var img = content.Descendants("img"); var postImages = img.Where(x => x.GetAttributeValue("class", null) != "mb-img"); var src = postImages.Select(x => x.GetAttributeValue("src", "")); var urls = src.Select(x => new Uri($"https:{x.Substring(0, x.LastIndexOf('!'))}")); return(src.Any() ? ImageResponse.FromImages(urls) : ImageResponse.FromNotFound(url)); }
/// <summary> /// Gets the id of the Diyidan user. /// </summary> /// <param name="client"></param> /// <param name="username"></param> /// <returns></returns> private static async Task <ulong> GetUserIdAsync(IDownloaderClient client, string username) { if (ulong.TryParse(username, out var val)) { return(val); } var query = new Uri($"https://www.diyidan.com/search/1?keyword={username}&search_type=user&post_type=综合"); var result = await client.GetHtmlAsync(() => client.GenerateReq(query)).CAF(); if (!result.IsSuccess) { throw new HttpRequestException("Unable to get the Diyidan user id."); } try { var li = result.Value.DocumentNode.Descendants("li"); var users = li.Where(x => x.GetAttributeValue("class", null) == "search_users_item users_item_"); var user = users.Single(x => { var usernameElement = x.Descendants("em").Single(y => y.GetAttributeValue("class", null) == "k_highlight"); return(usernameElement?.InnerText == username); }); var followingElement = user.Descendants("div").Single(x => x.GetAttributeValue("class", null) == "user_following_box"); return(Convert.ToUInt64(followingElement.GetAttributeValue("data-id", null))); } catch (Exception e) { throw new HttpRequestException("Unable to get the Diyidan user id.", e); } }
/// <summary> /// Generates a model with gotten json and the id/tags from <paramref name="jToken"/>. /// </summary> /// <param name="client"></param> /// <param name="jToken"></param> /// <returns></returns> private static async Task <Model> GenerateModel(IDownloaderClient client, JToken jToken) { var query = new Uri($"https://www.zerochan.net/{jToken["id"]}"); var result = await client.GetHtmlAsync(() => client.GenerateReq(query)).CAF(); if (!result.IsSuccess) { return(null); } var script = result.Value.DocumentNode.Descendants("script"); var json = script.Single(x => x.GetAttributeValue("type", null) == "application/ld+json"); var jObj = JObject.Parse(json.InnerText); //Add in the tags and id foreach (var innerToken in jToken.OfType <JProperty>()) { if (!jObj.ContainsKey(innerToken.Name)) { jObj.Add(innerToken); } } return(jObj.ToObject <Model>()); }
/// <inheritdoc /> protected override async Task GatherAsync(IDownloaderClient client, List <IPost> list, CancellationToken token) { using var valid = new CancellationTokenSource(); var subreddit = await _Reddit.GetSubredditAsync(Subreddit).CAF(); try { await subreddit.GetPosts(RedditSharp.Things.Subreddit.Sort.New, int.MaxValue).ForEachAsync(post => { valid.Token.ThrowIfCancellationRequested(); token.ThrowIfCancellationRequested(); if (post.CreatedUTC < OldestAllowed) { valid.Cancel(); } else if (post.IsStickied || post.IsSelfPost || post.Score < MinScore) { return; } else if (!Add(list, new Model(post))) { valid.Cancel(); } }, valid.Token).CAF(); } catch (OperationCanceledException) when(!token.IsCancellationRequested) { } }
/// <inheritdoc /> public async Task <ImageResponse> GetImagesAsync(IDownloaderClient client) { if (PostUrl.ToString().IsImagePath()) { return(ImageResponse.FromUrl(PostUrl)); } if (client.Gatherers.SingleOrDefault(x => x.IsFromWebsite(PostUrl)) is IImageGatherer gatherer) { return(await gatherer.FindImagesAsync(client, PostUrl).CAF()); } var result = await client.GetHtmlAsync(() => client.GenerateReq(PostUrl)).CAF(); if (result.IsSuccess) { var img = result.Value.DocumentNode.Descendants("img"); var src = img .Select(x => x.GetAttributeValue("src", null)) .Select(x => { if (Uri.TryCreate(x, UriKind.Absolute, out var uri) || Uri.TryCreate($"https://{PostUrl.Host}{x}", UriKind.Absolute, out uri)) { return(uri); } //How to check if relative to something other than just the host? return(null); }) .Where(x => x != null); if (src.Any()) { return(ImageResponse.FromImages(src)); } } return(ImageResponse.FromNotFound(PostUrl)); }
/// <summary> /// Gets the post with the specified id. /// </summary> /// <param name="client"></param> /// <param name="id"></param> /// <returns></returns> public static async Task <Model> GetInstagramPostAsync(IDownloaderClient client, string id) { var query = new Uri($"https://www.instagram.com/p/{id}/?__a=1"); var result = await client.GetTextAsync(() => client.GenerateReq(query)).CAF(); return(result.IsSuccess ? JsonConvert.DeserializeObject <InstagramGraphqlResult>(result.Value).Graphql.ShortcodeMedia : null); }
/// <summary> /// Gets the post with the specified id. /// </summary> /// <param name="client"></param> /// <param name="id"></param> /// <returns></returns> public static async Task <Model> GetAnimePicturesPostAsync(IDownloaderClient client, string id) { var query = new Uri($"https://anime-pictures.net/pictures/view_post/{id}?type=json&lang=en"); var result = await client.GetTextAsync(() => client.GenerateReq(query)).CAF(); return(result.IsSuccess ? JsonConvert.DeserializeObject <Model>(result.Value) : null); }
/// <summary> /// Gets the id of the Weibo user. /// </summary> /// <param name="client"></param> /// <param name="username"></param> /// <returns></returns> private static async Task <ulong> GetUserIdAsync(IDownloaderClient client, string username) { if (ulong.TryParse(username, out var val)) { return(val); } var query = new Uri($"https://s.weibo.com/user/{WebUtility.UrlEncode(username)}"); var result = await client.GetHtmlAsync(() => client.GenerateReq(query)).CAF(); if (!result.IsSuccess) { throw new HttpRequestException("Unable to get the Weibo user id."); } try { var a = result.Value.DocumentNode.Descendants("a"); var users = a.Where(x => x.GetAttributeValue("uid", null) != null); var user = users.First(x => x.GetAttributeValue("title", "").CaseInsEquals(username)); return(Convert.ToUInt64(user.GetAttributeValue("uid", null))); } catch (Exception e) { throw new HttpRequestException("Unable to get the Weibo user id.", e); } }
/// <summary> /// Gets the post with the specified id. /// </summary> /// <param name="client"></param> /// <param name="id"></param> /// <returns></returns> public static async Task <Model> GetVscoPostAsync(IDownloaderClient client, string id) { var query = new Uri($"https://vsco.co/ajxp/{await GetApiKeyAsync(client).CAF()}/2.0/medias/{id}"); var result = await client.GetTextAsync(() => client.GenerateReq(query)).CAF(); return(result.IsSuccess ? JObject.Parse(result.Value)["media"].ToObject <Model>() : null); }
/// <summary> /// Gets the images from the specified url. /// </summary> /// <param name="client"></param> /// <param name="url"></param> /// <returns></returns> public static async Task <ImageResponse> GetRedditImagesAsync(IDownloaderClient client, Uri url) { var u = DownloaderClient.RemoveQuery(url).ToString(); if (u.IsImagePath()) { return(ImageResponse.FromUrl(new Uri(u))); } const string search = "/comments/"; if (u.CaseInsIndexOf(search, out var index)) { var id = u.Substring(index + search.Length).Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries)[0]; if (await GetRedditPostAsync(id).CAF() is Model model) { return(await model.GetImagesAsync(client).CAF()); } } var parts = url.LocalPath.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); if (parts.Length == 1 && await GetRedditPostAsync(parts[0]).CAF() is Model post) { return(await post.GetImagesAsync(client).CAF()); } return(ImageResponse.FromNotFound(url)); }
/// <summary> /// Logs into pixiv, generating an access token. /// </summary> /// <param name="client"></param> /// <param name="username"></param> /// <param name="password"></param> /// <returns></returns> private static async Task <ApiKey> GetApiKeyAsync(IDownloaderClient client, string username, string password) { if (client.ApiKeys.TryGetValue(_Type, out var key) && (key.CreatedAt + key.ValidFor) > DateTime.UtcNow) { return(key); } var query = new Uri("https://oauth.secure.pixiv.net/auth/token"); var result = await client.GetTextAsync(() => { var req = client.GenerateReq(query, HttpMethod.Post); req.Content = new FormUrlEncodedContent(new Dictionary <string, string> { { "get_secure_url", "1" }, { "client_id", _ClientId }, { "client_secret", _ClientSecret }, { "grant_type", "password" }, { "username", username }, { "password", password }, }); return(req); }).CAF(); if (!result.IsSuccess) { throw new InvalidOperationException("Unable to login to Pixiv."); } var jObj = JObject.Parse(result.Value); var accessToken = jObj["response"]["access_token"].ToObject <string>(); var expiresIn = TimeSpan.FromSeconds(jObj["response"]["expires_in"].ToObject <int>()); return(client.ApiKeys[_Type] = new ApiKey(accessToken, expiresIn)); }
/// <summary> /// Initializes a new instance of the <see cref="DownloaderServiceConnection"/> class. /// </summary> /// <param name="clientType"> /// The client type. /// </param> /// <param name="serviceType"> /// The service type. /// </param> public DownloaderServiceConnection(IDownloaderClient clientType, Type serviceType) { this.messenger = new Messenger(new Handler(this.SendMessage)); this.serviceConnection = new ServiceConnection(this); this.clientType = clientType; this.serviceTypeType = serviceType; }
/// <summary> /// Gets the images from the specified url. /// </summary> /// <param name="client"></param> /// <param name="url"></param> /// <returns></returns> public static async Task <ImageResponse> GetPawooImagesAsync(IDownloaderClient client, Uri url) { var u = DownloaderClient.RemoveQuery(url).ToString(); if (u.IsImagePath()) { return(ImageResponse.FromUrl(new Uri(u))); } const string search = "/statuses/"; if (u.CaseInsIndexOf(search, out var index)) { var id = u.Substring(index + search.Length).Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries)[0]; if (await GetPawooPostAsync(client, id).CAF() is Model post) { return(await post.GetImagesAsync(client).CAF()); } } if (u.Contains("@")) { var id = u.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries).Last(); if (await GetPawooPostAsync(client, id).CAF() is Model post) { return(await post.GetImagesAsync(client).CAF()); } } return(ImageResponse.FromNotFound(url)); }
/// <summary> /// Gets the post with the specified id. /// </summary> /// <param name="client"></param> /// <param name="id"></param> /// <returns></returns> public static async Task <Model> GetArtstationPostAsync(IDownloaderClient client, string id) { var query = new Uri($"https://www.artstation.com/projects/{id}.json"); var result = await client.GetTextAsync(() => client.GenerateReq(query)).CAF(); return(result.IsSuccess ? JsonConvert.DeserializeObject <Model>(result.Value) : null); }
/// <summary> /// Gets the post with the specified id. /// </summary> /// <param name="client"></param> /// <param name="id"></param> /// <returns></returns> public static async Task <Model> GetYanderePostAsync(IDownloaderClient client, string id) { var query = GenerateYandereQuery($"id:{id}", 0); var result = await client.GetTextAsync(() => client.GenerateReq(query)).CAF(); return(result.IsSuccess ? ParseYanderePosts(result.Value)[0] : null); }
/// <inheritdoc /> public async Task <ImageResponse> GetImagesAsync(IDownloaderClient client) { //Only one image, so return the one image's url if (PageCount == 1) { return(ImageResponse.FromUrl(ImageUrls["large"])); } //Metadata is null so we need to get it again else if (Metadata == null) { var query = new Uri($"https://public-api.secure.pixiv.net/v1/works/{Id}.json" + $"?access_token={client.ApiKeys[typeof(PixivPostDownloader)]}" + "&include_stats=1" + "&include_sanity_level=1" + "&image_sizes=large" + "&inclue_metadata=1" + "&include_content_type=1"); var result = await client.GetTextAsync(() => client.GenerateReq(query)).CAF(); if (!result.IsSuccess) { throw new InvalidOperationException("Unable to use the Pixiv api."); } //First b/c returns a list Metadata = JObject.Parse(result.Value)["response"].First["metadata"].ToObject <PixivPostMetadata>(); } return(ImageResponse.FromImages(Metadata.Pages.Select(x => x.ImageUrls["large"]))); }
/// <summary> /// Gets the id of the Bcy user. /// </summary> /// <param name="client"></param> /// <param name="username"></param> /// <returns></returns> private static async Task <ulong> GetUserIdAsync(IDownloaderClient client, string username) { if (ulong.TryParse(username, out var val)) { return(val); } var query = new Uri($"https://bcy.net/search/user?k={username}"); var result = await client.GetHtmlAsync(() => client.GenerateReq(query)).CAF(); if (!result.IsSuccess) { throw new HttpRequestException("Unable to get the Bcy user id."); } try { var a = result.Value.DocumentNode.Descendants("a"); var user = a.First(x => x.GetAttributeValue("title", "").CaseInsEquals(username)); return(Convert.ToUInt64(user.GetAttributeValue("href", null).Replace("/u/", ""))); } catch (Exception e) { throw new HttpRequestException("Unable to get the Bcy user id.", e); } }
/// <summary> /// Gets the post with the specified id. /// </summary> /// <param name="client"></param> /// <param name="id"></param> /// <returns></returns> public static async Task <Model> GetWeiboPostAsync(IDownloaderClient client, string id) { var query = new Uri($"https://m.weibo.cn/api/statuses/show?id={id}"); var result = await client.GetTextAsync(() => client.GenerateReq(query)).CAF(); return(result.IsSuccess ? JsonConvert.DeserializeObject <Model>(result.Value) : null); }
/// <summary> /// Gets the post with the specified id. /// </summary> /// <param name="client"></param> /// <param name="id"></param> /// <returns></returns> public static async Task <Model> GetPawooPostAsync(IDownloaderClient client, string id) { //This API call does not require authentication. var query = new Uri($"https://www.pawoo.net/api/v1/statuses/{id}"); var result = await client.GetTextAsync(() => client.GenerateReq(query)).CAF(); return(result.IsSuccess ? JsonConvert.DeserializeObject <Model>(result.Value) : null); }
public DownloaderService(IDownloaderClient downloaderService) { this.downloaderService = downloaderService; downloadStatuses = new(); availableUrisToDownload = new SemaphoreSlim(0); readLock = new SemaphoreSlim(1, 1); }
/// <inheritdoc /> protected override async Task GatherAsync(IDownloaderClient client, List <IPost> list, CancellationToken token) { var parsed = new PixivPage(); //Iterate because it's easy and has less strain for (var i = 0; list.Count < AmountOfPostsToGather && (i == 0 || parsed.Count >= 100); ++i) { token.ThrowIfCancellationRequested(); var query = new Uri($"https://public-api.secure.pixiv.net/v1/users/{UserId}/works.json" + $"?access_token={await GetApiKeyAsync(client, LoginUsername, LoginPassword).CAF()}" + $"&page={i + 1}" + "&per_page=100" + "&include_stats=1" + "&include_sanity_level=1" + "&image_sizes=large"); //This is an array of sizes separated by commas, but we only care about large var result = await client.GetTextAsync(() => client.GenerateReq(query)).CAF(); if (!result.IsSuccess) { //If there's an error with the access token, try to get another one if (result.Value.Contains("access token")) { //Means the access token cannot be gotten if (!client.ApiKeys.ContainsKey(_Type)) { return; } client.ApiKeys.Remove(_Type); --i; //Decrement since this iteration is useless continue; } return; } parsed = JsonConvert.DeserializeObject <PixivPage>(result.Value); foreach (var post in parsed.Posts) { token.ThrowIfCancellationRequested(); if (post.CreatedAt < OldestAllowed) { return; } if (post.Score < MinScore) { continue; } //Don't think the API has an endpoint that holds the sizes of every image? //if (!HasValidSize(post, out _)) //{ // continue; //} if (!Add(list, post)) { return; } } } }
/// <summary> /// Logs into Pawoo, generating an access token. /// </summary> /// <param name="client"></param> /// <param name="username"></param> /// <param name="password"></param> /// <returns></returns> private static async Task <ApiKey> GetApiKeyAsync(IDownloaderClient client, string username, string password) { if (client.ApiKeys.TryGetValue(_Type, out var key)) { return(key); } var authTokenQuery = new Uri("https://pawoo.net/auth/sign_in"); var authTokenResult = await client.GetHtmlAsync(() => client.GenerateReq(authTokenQuery)).CAF(); if (!authTokenResult.IsSuccess) { throw new HttpRequestException("Unable to gather the authenticity token for login."); } var input = authTokenResult.Value.DocumentNode.Descendants("input"); var authTokenElement = input.Single(x => x.GetAttributeValue("name", null) == "authenticity_token"); var authToken = authTokenElement.GetAttributeValue("value", null); if (string.IsNullOrWhiteSpace(authToken)) { throw new HttpRequestException("Unable to find the authenticity token for login."); } using var data = new FormUrlEncodedContent(new Dictionary <string, string> { { "utf8", "✓" }, { "authenticity_token", authToken }, { "user[email]", username }, { "user[password]", password }, }); var loginQuery = new Uri("https://pawoo.net/auth/sign_in"); var loginResult = await client.GetTextAsync(() => { var req = client.GenerateReq(loginQuery, HttpMethod.Post); req.Content = data; return(req); }).CAF(); if (!loginResult.IsSuccess) { throw new InvalidOperationException("Unable to login to Pawoo."); } //Load a random user's page so we can scrape the API key from it var query = new Uri("https://pawoo.net/web/timelines/home"); var result = await client.GetTextAsync(() => client.GenerateReq(query)).CAF(); if (!result.IsSuccess) { throw new HttpRequestException("Unable to get the access token."); } const string search = "\"access_token\":\""; var cut = result.Value.Substring(result.Value.IndexOf(search) + search.Length); return(client.ApiKeys[_Type] = new ApiKey(cut.Substring(0, cut.IndexOf('"')))); }
/// <inheritdoc /> public Task <ImageResponse> GetImagesAsync(IDownloaderClient client) { if (Photos?.Count > 0) { var urls = Photos.Select(x => x.FullSizeImageUrl).ToArray(); return(Task.FromResult(ImageResponse.FromImages(urls))); } return(Task.FromResult(ImageResponse.FromUrl(FullSizeImageUrl))); }
/// <inheritdoc /> protected override Task GatherAsync(IDownloaderClient client, List <IPost> list, CancellationToken token) { return(GatheringMethod switch { DeviantArtGatheringMethod.Scraping => GetPostsThroughScraping(client, list, token), DeviantArtGatheringMethod.Api => GetPostsThroughApi(client, list, token), DeviantArtGatheringMethod.Rss => GetPostsThroughRss(client, list, token), _ => throw new ArgumentOutOfRangeException(nameof(GatheringMethod)), });
/// <inheritdoc /> protected override async Task GatherAsync(IDownloaderClient client, List <IPost> list, CancellationToken token) { var parsed = new List <Model>(); var validToken = false; //Iterate to get the next page of results for (var i = 0; list.Count < AmountOfPostsToGather && (i == 0 || parsed.Count >= 60); ++i) { token.ThrowIfCancellationRequested(); var query = new Uri($"https://api.imgur.com/3/gallery/search/time/all/{i}/" + $"?client_id={await GetApiKeyAsync(client, validToken).CAF()}" + $"&q={WebUtility.UrlEncode(Tags)}"); var result = await client.GetTextAsync(() => client.GenerateReq(query)).CAF(); if (!result.IsSuccess) { //If there's an error with the api key, try to get another one if (result.Value.Contains("client_id")) { validToken = false; continue; } throw new HttpRequestException("Unable to gather more Imgur posts.\n\n" + result.Value); } validToken = true; parsed = JObject.Parse(result.Value)["data"].ToObject <List <Model> >(); foreach (var post in parsed) { token.ThrowIfCancellationRequested(); if (post.CreatedAt < OldestAllowed) { return; } if (post.Score < MinScore) { continue; } //Get all images then make sure they're valid await post.SetAllImages(client).CAF(); foreach (var image in post.Images.Where(x => !HasValidSize(x, out _)).ToList()) { post.Images.Remove(image); } if (post.Images.Count == 0) { continue; } if (!Add(list, post)) { return; } } } }
/// <inheritdoc /> public Task <ImageResponse> GetImagesAsync(IDownloaderClient client) { if (ExtendedEntities.Media == null) { return(Task.FromResult(ImageResponse.FromNotFound(PostUrl))); } var urls = ExtendedEntities.Media.Select(x => new Uri($"{x.MediaUrlHttps}:orig")); return(Task.FromResult(ImageResponse.FromImages(urls))); }
/// <summary> /// Gets the images from the specified url. /// </summary> /// <param name="client"></param> /// <param name="url"></param> /// <returns></returns> public static async Task <ImageResponse> GetLofterImagesAsync(IDownloaderClient client, Uri url) { var result = await client.GetHtmlAsync(() => client.GenerateReq(url)).CAF(); var div = result.Value.DocumentNode.Descendants("div"); var pics = div.Where(x => x.GetAttributeValue("class", null) == "pic").Select(x => x.Descendants("a").Single()); var urls = pics.Select(x => new Uri(x.GetAttributeValue("bigimgsrc", null).Split('?')[0])); return(ImageResponse.FromImages(urls)); }
/// <inheritdoc /> protected override async Task GatherAsync(IDownloaderClient client, List <IPost> list, CancellationToken token) { var parsed = new TumblrPage(); //Iterate because the results are in pages for (var i = 0; list.Count < AmountOfPostsToGather && (i == 0 || parsed.Posts?.Count > 0); i += parsed.Posts?.Count ?? 0) { token.ThrowIfCancellationRequested(); var query = new Uri($"http://{Username}.tumblr.com/api/read/json" + "?debug=1" + "&type=photo" + "&filter=text" + "&num=50" + $"&start={i}"); var result = await client.GetTextAsync(() => client.GenerateReq(query)).CAF(); if (!result.IsSuccess) { return; } parsed = JsonConvert.DeserializeObject <TumblrPage>(result.Value.Split(new[] { '=' }, 2)[1].Trim().TrimEnd(';')); foreach (var post in parsed.Posts) { token.ThrowIfCancellationRequested(); if (post.CreatedAt < OldestAllowed) { return; } if (post.Score < MinScore) { continue; } if (post.Photos.Count > 0) //Going into here means there is more than one photo { foreach (var photo in post.Photos.Where(x => !HasValidSize(x, out _)).ToList()) { post.Photos.Remove(photo); } if (post.Photos.Count == 0) { continue; } } else if (!HasValidSize(post, out _)) //Going into here means there is one photo { continue; } if (!Add(list, post)) { return; } } } }
/// <summary> /// Gets the id of the Vsco user. /// </summary> /// <param name="client"></param> /// <param name="username"></param> /// <returns></returns> public static async Task <ulong> GetUserIdAsync(IDownloaderClient client, string username) { var query = new Uri($"https://vsco.co/ajxp/{await GetApiKeyAsync(client).CAF()}/2.0/sites?subdomain={username}"); var result = await client.GetTextAsync(() => client.GenerateReq(query)).CAF(); if (!result.IsSuccess) { throw new HttpRequestException("Unable to get the user's id."); } return(JsonConvert.DeserializeObject <VscoUserResults>(result.Value).Users.Single().Id); }
/// <summary> /// Gets the post with the specified id. /// </summary> /// <param name="client"></param> /// <param name="id"></param> /// <returns></returns> public static async Task <TwitterOAuthPost> GetTwitterPostAsync(IDownloaderClient client, string id) { var query = new Uri($"https://api.twitter.com/1.1/statuses/show.json?id={id}"); var result = await client.GetTextAsync(() => { var req = client.GenerateReq(query); req.Headers.Add("Authorization", $"Bearer {_Token}"); return(req); }, TimeSpan.FromMinutes(15)).CAF(); return(result.IsSuccess ? JsonConvert.DeserializeObject <TwitterOAuthPost>(result.Value) : null); }
/// <summary> /// Returns a stub object that, when connected, will listen for /// marshaled <see cref="IDownloaderClient"/> methods and translate /// them into calls to the supplied interface. /// </summary> /// <param name="itf"> /// An implementation of IDownloaderClient that will be called when /// remote method calls are unmarshaled. /// </param> /// <param name="downloaderService"> /// The class for your implementation of<see cref="ExpansionDownloader.Service.DownloaderService"/>. /// </param> /// <returns> /// The <see cref="IDownloaderServiceConnection"/> that allows you to connect to the service /// such that your <see cref="IDownloaderClient"/> receives status updates. /// </returns> public static IDownloaderServiceConnection CreateStub(IDownloaderClient itf, Type downloaderService) { return new DownloaderServiceConnection(itf, downloaderService); }
/// <summary> /// Called in response to OnClientUpdated. Creates a new proxy and /// notifies it of the current state. /// </summary> /// <param name="msg"> /// the client Messenger to notify /// </param> public void SetMessenger(Messenger msg) { this.clientProxy = ClientMarshaller.CreateProxy(msg); if (null != this.progressInfo) { this.clientProxy.OnDownloadProgress(this.progressInfo); } if (this.clientState != DownloaderState.Unknown) { this.clientProxy.OnDownloadStateChanged(this.clientState); } }