Exemplo n.º 1
0
        private async Task <List <Post> > GetUnfetchedPostsAsync(Fetcher fetcher,
                                                                 string blog, string tag, FilePlan plan, Dictionary <Media, long> medias)
        {
            var posts = new ConcurrentBag <Post>();

            var block = new ActionBlock <Media>(
                async media =>
            {
                int offset = 0;

                while (true)
                {
                    var postSet = await fetcher.GetPostsAsync(
                        blog, media, tag, offset);

                    logger.LogTrace($"Got {postSet} (Offset: {offset}, TotalPosts: {postSet.TotalPosts:N0})");

                    if (postSet.Count == 0)
                    {
                        return;
                    }

                    foreach (var post in postSet)
                    {
                        posts.Add(post);
                    }

                    if (postSet.Last().PostId <= medias[media])
                    {
                        return;
                    }

                    offset += 20;
                }
            },
                new ExecutionDataflowBlockOptions()
            {
                MaxDegreeOfParallelism = Environment.ProcessorCount
            });

            medias.Keys.ToList().ForEach(m => block.Post(m));

            block.Complete();

            await block.Completion;

            return(posts.OrderByDescending(p => p.PostId).ToList());
        }
Exemplo n.º 2
0
        private async Task FetchMediasAsync(string folder, FilePlan plan, List <Post> posts)
        {
            var client = new HttpClient();

            var jobber = new TransformManyBlock <Post, FetchJob>(
                post =>
            {
                var jobs = new List <FetchJob>();

                if (post.Media != Media.Photo)
                {
                    jobs.Add(GetJob(post, post.VideoUri, null));
                }
                else
                {
                    if (post.PhotoUris.Count == 1)
                    {
                        jobs.Add(GetJob(post, post.PhotoUris[0], null));
                    }
                    else
                    {
                        for (int i = 0; i < post.PhotoUris.Count; i++)
                        {
                            jobs.Add(GetJob(post, post.PhotoUris[i], i));
                        }
                    }
                }

                return(jobs);
            });

            var fetcher = new ActionBlock <FetchJob>(
                async job =>
            {
                if (plan == FilePlan.Add && job.Exists(folder))
                {
                    logger.LogDebug($"Skipped \"{job.FileName}\"");

                    return;
                }

                var response = await client.GetAsync(job.Uri);

                if (response.IsSuccessStatusCode)
                {
                    var stream = await response.Content.ReadAsStreamAsync();

                    await job.SaveToFileAsync(stream, folder);

                    logger.LogInformation($"Fetched \"{job.FileName}\"");
                }
                else
                {
                    var sb = new StringBuilder();

                    sb.Append(response.ReasonPhrase);
                    sb.Append(" (StatusCode: ");
                    sb.Append(response.StatusCode);
                    sb.Append(", FileName: ");
                    sb.Append(job.FileName);
                    sb.Append(", Uri: ");
                    sb.Append(job.Uri);
                    sb.Append(")");

                    logger.LogWarning(sb.ToString());
                }
            },
                new ExecutionDataflowBlockOptions()
            {
                MaxDegreeOfParallelism = Environment.ProcessorCount
            });

            jobber.LinkTo(fetcher, new DataflowLinkOptions {
                PropagateCompletion = true
            });

            posts.ForEach(post => jobber.Post(post));

            jobber.Complete();

            await fetcher.Completion;
        }