Esempio n. 1
0
        /// <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('"'))));
        }
Esempio n. 2
0
        /// <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);
        }
Esempio n. 3
0
        /// <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);
        }
Esempio n. 4
0
        /// <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));
        }
Esempio n. 5
0
        /// <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);
        }
Esempio n. 6
0
        /// <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"])));
        }
Esempio n. 7
0
        /// <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);
        }
Esempio n. 8
0
        /// <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);
        }
Esempio n. 9
0
        /// <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);
        }
Esempio n. 10
0
        /// <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);
        }
Esempio n. 11
0
        /// <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;
                    }
                }
            }
        }
Esempio n. 12
0
        /// <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;
                    }
                }
            }
        }
Esempio n. 13
0
        /// <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;
                    }
                }
            }
        }
Esempio n. 14
0
        /// <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);
        }
Esempio n. 15
0
        /// <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>
        /// Gets the post with the specified id.
        /// </summary>
        /// <param name="client"></param>
        /// <param name="url">The url to gather. Can be in fav.me/id or post link format.</param>
        /// <returns></returns>
        public static async Task <DeviantArtOEmbedPost> GetDeviantArtPostAsync(IDownloaderClient client, Uri url)
        {
            var query  = new Uri($"https://backend.deviantart.com/oembed?url={url}");
            var result = await client.GetTextAsync(() => client.GenerateReq(query)).CAF();

            if (result.IsSuccess)
            {
                var jObj = JObject.Parse(result.Value);
                jObj.Add(nameof(DeviantArtOEmbedPost.PostUrl), url);
                return(jObj.ToObject <DeviantArtOEmbedPost>());
            }
            return(null);
        }
Esempio n. 17
0
        /// <inheritdoc />
        protected override async Task GatherAsync(IDownloaderClient client, List <IPost> list, CancellationToken token)
        {
            var userId = await GetUserIdAsync(client, Username).CAF();

            var parsed = new List <Model>();

            for (var i = 0; list.Count < AmountOfPostsToGather && (i == 0 || parsed.Count >= 10); ++i)
            {
                token.ThrowIfCancellationRequested();
                var query = new Uri("https://m.weibo.cn/api/container/getIndex" +
                                    $"?containerid=230413{userId}_-_longbloglist" +
                                    $"&page={i + 1}");
                var result = await client.GetTextAsync(() => client.GenerateReq(query)).CAF();

                if (!result.IsSuccess)
                {
                    return;
                }

                parsed = JObject.Parse(result.Value)["data"]["cards"].Select(x => x["mblog"].ToObject <Model>()).ToList();
                foreach (var post in parsed)
                {
                    token.ThrowIfCancellationRequested();
                    if (post.CreatedAt < OldestAllowed)
                    {
                        return;
                    }
                    if (post.Score < MinScore)
                    {
                        continue;
                    }
                    if (post.Pictures == null)
                    {
                        continue;
                    }
                    //Remove all images that are too small to be downloaded
                    foreach (var picture in post.Pictures.Where(x => !HasValidSize(x.Large.Geo, out _)).ToList())
                    {
                        post.Pictures.Remove(picture);
                    }
                    if (post.Pictures.Count == 0)
                    {
                        continue;
                    }
                    if (!Add(list, post))
                    {
                        return;
                    }
                }
            }
        }
Esempio n. 18
0
        /// <inheritdoc />
        protected override async Task GatherAsync(IDownloaderClient client, List <IPost> list, CancellationToken token)
        {
            var userId = 0UL;
            var parsed = new VscoPage();

            //Iterate because the results are in pages
            for (var i = 0; list.Count < AmountOfPostsToGather && (i == 0 || parsed.Posts.Count > 0); ++i)
            {
                token.ThrowIfCancellationRequested();
                if (userId == 0UL)
                {
                    userId = await GetUserIdAsync(client, Username).CAF();
                }

                var query = new Uri($"https://vsco.co/ajxp/{await GetApiKeyAsync(client).CAF()}/2.0/medias" +
                                    $"?site_id={userId}" +
                                    $"&page={i}");
                var result = await client.GetTextAsync(() => client.GenerateReq(query)).CAF();

                if (!result.IsSuccess)
                {
                    //If there's an error with authorization, try to get a new key
                    if (result.StatusCode == HttpStatusCode.Unauthorized)
                    {
                        client.ApiKeys.Remove(_Type);
                        --i;
                        continue;
                    }
                    return;
                }

                parsed = JsonConvert.DeserializeObject <VscoPage>(result.Value);
                foreach (var post in parsed.Posts)
                {
                    token.ThrowIfCancellationRequested();
                    if (post.CreatedAt < OldestAllowed)
                    {
                        return;
                    }
                    if (!HasValidSize(post, out _))
                    {
                        continue;
                    }
                    if (!Add(list, post))
                    {
                        return;
                    }
                }
            }
        }
Esempio n. 19
0
        /// <summary>
        /// Returns the id of the user.
        /// </summary>
        /// <param name="client"></param>
        /// <param name="username"></param>
        /// <returns></returns>
        private static async Task <ulong> GetUserIdAsync(IDownloaderClient client, string username)
        {
            var query  = new Uri($"https://pawoo.net/{username}/");
            var result = await client.GetTextAsync(() => client.GenerateReq(query)).CAF();

            if (!result.IsSuccess)
            {
                throw new HttpRequestException("Unable to get the user id.");
            }
            const string search = "/api/salmon/";
            var          cut    = result.Value.Substring(result.Value.IndexOf(search) + search.Length);

            return(Convert.ToUInt64(cut.Substring(0, cut.IndexOf('\''))));
        }
Esempio n. 20
0
        /// <summary>
        /// Gets the id of a board.
        /// </summary>
        /// <returns></returns>
        private static async Task <string> GetBoardId(IDownloaderClient client, Uri url)
        {
            var result = await client.GetTextAsync(() => client.GenerateReq(url)).CAF();

            if (!result.IsSuccess)
            {
                throw new HttpRequestException("Unable to get the board id.");
            }

            const string search = "\"board_id\": \"";
            var          cut    = result.Value.Substring(result.Value.IndexOf(search) + search.Length);

            return(cut.Substring(0, cut.IndexOf('"')));
        }
Esempio n. 21
0
        /// <summary>
        /// Gets the id of the user.
        /// </summary>
        /// <param name="client"></param>
        /// <param name="username"></param>
        /// <returns></returns>
        private static async Task <string> GetUserIdAsync(IDownloaderClient client, string username)
        {
            var query  = new Uri($"https://www.flickr.com/photos/{username}");
            var result = await client.GetTextAsync(() => client.GenerateReq(query)).CAF();

            if (!result.IsSuccess)
            {
                throw new HttpRequestException("Unable to get the Flickr user's id.");
            }

            const string search = "\"ownerNsid\":\"";
            var          cut    = result.Value.Substring(result.Value.IndexOf(search) + search.Length);

            return(cut.Substring(0, cut.IndexOf('"')));
        }
Esempio n. 22
0
        /// <summary>
        /// Gets the post with the specified id.
        /// </summary>
        /// <param name="client"></param>
        /// <param name="username"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        public static async Task <Model> GetTumblrPostAsync(IDownloaderClient client, string username, string id)
        {
            var query  = new Uri($"http://{username}.tumblr.com/api/read/json?debug=1&id={id}");
            var result = await client.GetTextAsync(() => client.GenerateReq(query)).CAF();

            if (result.IsSuccess)
            {
                var post = JObject.Parse(result.Value.Split(new[] { '=' }, 2)[1].Trim().TrimEnd(';'))["posts"].First;
                //If the id doesn't match, then that means it just got random values and the id is invalid
                if (post["id"].ToString() == id)
                {
                    return(post.ToObject <Model>());
                }
            }
            return(null);
        }
Esempio n. 23
0
        /// <inheritdoc />
        protected override async Task GatherAsync(IDownloaderClient client, List <IPost> list, CancellationToken token)
        {
            var parsed = new ArtstationPage();

            //Iterate to get the next page of results
            for (var i = 0; list.Count < AmountOfPostsToGather && (i == 0 || parsed.Posts.Count >= 50); ++i)
            {
                token.ThrowIfCancellationRequested();
                var query  = new Uri($"https://www.artstation.com/users/{Username}/projects.json?page={i}");
                var result = await client.GetTextAsync(() => client.GenerateReq(query)).CAF();

                if (!result.IsSuccess)
                {
                    return;
                }

                parsed = JsonConvert.DeserializeObject <ArtstationPage>(result.Value);
                foreach (var post in parsed.Posts)
                {
                    token.ThrowIfCancellationRequested();
                    var fullPost = await GetArtstationPostAsync(client, post.Id).CAF();

                    if (fullPost.CreatedAt < OldestAllowed)
                    {
                        return;
                    }
                    if (fullPost.Score < MinScore)
                    {
                        continue;
                    }
                    //Remove all images that don't meet the size requirements
                    foreach (var image in fullPost.Assets.Where(x => x.AssetType != "image" || !HasValidSize(x, out _)).ToList())
                    {
                        fullPost.Assets.Remove(image);
                    }
                    if (fullPost.Assets.Count == 0)
                    {
                        continue;
                    }
                    if (!Add(list, fullPost))
                    {
                        return;
                    }
                }
            }
        }
Esempio n. 24
0
        /// <summary>
        /// Gets the post with the specified id.
        /// </summary>
        /// <param name="client"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        public static async Task <Model> GetPinterestPostAsync(IDownloaderClient client, string id)
        {
            var options = new Dictionary <string, object>
            {
                { "id", id },
                { "field_set_key", "detailed" },
            };
            const string endpoint = "/PinResource/get/";
            var          result   = await client.GetTextAsync(() =>
            {
                var req = client.GenerateReq(GenerateQuery(endpoint, options));
                req.Headers.Add("X-Requested-With", "XMLHttpRequest");
                return(req);
            }).CAF();

            return(result.IsSuccess ? JObject.Parse(result.Value)["resource_response"]["data"].ToObject <Model>() : null);
        }
Esempio n. 25
0
        /// <summary>
        /// Gets the post with the specified id.
        /// </summary>
        /// <param name="client"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        public static async Task <Model> GetFlickrPostAsync(IDownloaderClient client, string id)
        {
            var query  = new Uri($"{await GenerateApiQueryAsync(client, 0).CAF()}&method=flickr.photos.getInfo&photo_id={id}");
            var result = await client.GetTextAsync(() => client.GenerateReq(query)).CAF();

            if (!result.IsSuccess)
            {
                return(null);
            }
            return(JObject.Parse(result.Value)["photo"].ToObject <Model>(JsonSerializer.Create(new JsonSerializerSettings
            {
                Error = (obj, e) =>
                {
                    //Eat any exceptions for unexpected start objects, since json doesn't like unmapped nested objects
                    e.ErrorContext.Handled = e.ErrorContext.Error.ToString().Contains("StartObject. Path 'photo.");
                },
            })));
        }
Esempio n. 26
0
        /// <summary>
        /// Gets an api key for Vsco.
        /// </summary>
        /// <param name="client"></param>
        /// <returns></returns>
        public static async Task <ApiKey> GetApiKeyAsync(IDownloaderClient client)
        {
            if (client.ApiKeys.TryGetValue(_Type, out var key))
            {
                return(key);
            }
            var time   = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
            var query  = new Uri($"https://vsco.co/content/Static/userinfo?callback=jsonp_{time}_0");
            var result = await client.GetTextAsync(() => client.GenerateReq(query)).CAF();

            if (!result.IsSuccess)
            {
                throw new HttpRequestException("Unable to get the api key.");
            }
            var cookie = client.Cookies.GetCookies(query)["vs"].Value;

            return(client.ApiKeys[_Type] = new ApiKey(cookie));
        }
Esempio n. 27
0
        /// <inheritdoc />
        protected override async Task GatherAsync(IDownloaderClient client, List <IPost> list, CancellationToken token)
        {
            var userId = await GetUserIdAsync(client, Username).CAF();

            var parsed = new List <Model>();

            //Iterate becasue there's a limit of 20 per page
            for (var i = 0; list.Count < AmountOfPostsToGather && (i == 0 || parsed.Count >= 20); ++i)
            {
                token.ThrowIfCancellationRequested();
                var query = new Uri("https://bcy.net/home/timeline/loaduserposts" +
                                    $"?since={(parsed.Count > 0 ? parsed.Last().Id : "0")}" +
                                    $"&uid={userId}" +
                                    "&limit=20" +
                                    "&source=all" +
                                    "&filter=origin");
                var result = await client.GetTextAsync(() => client.GenerateReq(query)).CAF();

                if (!result.IsSuccess)
                {
                    return;
                }

                parsed = JObject.Parse(result.Value)["data"].Select(x => x["item_detail"].ToObject <Model>()).ToList();
                foreach (var post in parsed)
                {
                    token.ThrowIfCancellationRequested();
                    if (post.CreatedAt < OldestAllowed)
                    {
                        return;
                    }
                    //First check indicates the post doesn't have any images
                    //Due to the way this site's api is set up can't check image sizes
                    if (post.PicNum < 1 || post.Score < MinScore)
                    {
                        continue;
                    }
                    if (!Add(list, post))
                    {
                        return;
                    }
                }
            }
        }
Esempio n. 28
0
        /// <summary>
        /// Gets an api key for Flickr.
        /// </summary>
        /// <param name="client"></param>
        /// <returns></returns>
        private static async Task <ApiKey> GetApiKeyAsync(IDownloaderClient client)
        {
            if (client.ApiKeys.TryGetValue(_Type, out var key))
            {
                return(key);
            }

            var query  = new Uri("https://www.flickr.com");
            var result = await client.GetTextAsync(() => client.GenerateReq(query)).CAF();

            if (!result.IsSuccess)
            {
                throw new HttpRequestException("Unable to get the Flickr api key.");
            }

            const string search = "api.site_key = \"";
            var          cut    = result.Value.Substring(result.Value.IndexOf(search) + search.Length);

            return(client.ApiKeys[_Type] = new ApiKey(cut.Substring(0, cut.IndexOf('"'))));
        }
Esempio n. 29
0
        /// <summary>
        /// Gets an api key for Instagram.
        /// </summary>
        /// <param name="client"></param>
        /// <returns></returns>
        private static async Task <ApiKey> GetApiKeyAsync(IDownloaderClient client)
        {
            if (client.ApiKeys.TryGetValue(_Type, out var key))
            {
                return(key);
            }

            //Load the page regularly first so we can get some data from it
            var query  = new Uri("https://www.instagram.com/instagram/?hl=en");
            var result = await client.GetHtmlAsync(() => client.GenerateReq(query)).CAF();

            if (!result.IsSuccess)
            {
                throw new HttpRequestException("Unable to get the first request to the user's account.");
            }

            //Find the direct link to ProfilePageContainer.js
            var jsLink = result.Value.DocumentNode.Descendants("link")
                         .Select(x => x.GetAttributeValue("href", ""))
                         .First(x => x.Contains("ProfilePageContainer.js"));
            var jsQuery  = new Uri($"https://www.instagram.com{jsLink}");
            var jsResult = await client.GetTextAsync(() => client.GenerateReq(jsQuery)).CAF();

            if (!jsResult.IsSuccess)
            {
                throw new HttpRequestException("Unable to get the request to the Javascript holding the query hash.");
            }

            //Read ProfilePageContainer.js and find the query id
            //There are multiple query ids in this file, and Instagram likes changing the location of each valid one,
            //so we have to do some searching with long strings and regex
            //(o=e.profilePosts.byUserId.get(t))||void 0===o?void 0:o.pagination},queryId:\"
            //(n=e.profilePosts.byUserId.get(t))||void 0===n?void 0:n.pagination},queryId:\"
            const string alpha   = "[a-zA-Z]";
            var          qSearch = $@"\({alpha}={alpha}\.profilePosts\.byUserId\.get\(t\)\)\|\|void 0==={alpha}\?void 0:{alpha}\.pagination}},queryId:""";
            var          qMatch  = Regex.Matches(jsResult.Value, qSearch).Cast <Match>().Single();
            var          qCut    = jsResult.Value.Substring(qMatch.Index + qMatch.Length);
            var          q       = qCut.Substring(0, qCut.IndexOf('"'));

            return(client.ApiKeys[_Type] = new ApiKey(q));
        }
Esempio n. 30
0
        /// <inheritdoc />
        protected override async Task GatherAsync(IDownloaderClient client, List <IPost> list, CancellationToken token)
        {
            var parsed = new List <Model>();

            for (var i = 0; list.Count < AmountOfPostsToGather && (i == 0 || parsed.Count >= 24); ++i, parsed.Clear())
            {
                token.ThrowIfCancellationRequested();
                var query = new Uri($"https://www.zerochan.net/{WebUtility.UrlEncode(Tags)}" +
                                    "?s=id" +
                                    $"&p={i + 1}" +
                                    "&json");
                var result = await client.GetTextAsync(() => client.GenerateReq(query)).CAF();

                if (!result.IsSuccess)
                {
                    return;
                }

                foreach (var item in JObject.Parse(result.Value)["items"])
                {
                    token.ThrowIfCancellationRequested();

                    var post = await GenerateModel(client, item).CAF();

                    parsed.Add(post);

                    if (post.CreatedAt < OldestAllowed)
                    {
                        return;
                    }
                    if (!HasValidSize(post, out _) || post.Score < MinScore)
                    {
                        continue;
                    }
                    if (!Add(list, post))
                    {
                        return;
                    }
                }
            }
        }