コード例 #1
0
ファイル: FeedManager.cs プロジェクト: GorkyR/Fidd
    public async Task AddFeedAsync(string feed_url)
    {
        var found_feed_urls = from url in await FeedReader.GetFeedUrlsFromUrlAsync(feed_url) select url.Url;

        if (found_feed_urls.Count() > 0)
        {
            var blog_url = found_feed_urls.First();
            feed_url = blog_url.StartsWith('/') ? $"{feed_url.TrimEnd('/')}{blog_url}" : blog_url;
        }

        if (Feeds.Any(f => f.FeedLink == feed_url))
        {
            throw new Exception("There's already a feed with that url.");
        }
        else
        {
            var parsed_feed = await FeedReader.ReadAsync(feed_url);

            var feed_uri   = new Uri(parsed_feed.Link);
            var feed_title = string.IsNullOrWhiteSpace(parsed_feed.Title) ? feed_uri.Host : parsed_feed.Title;
            var feed_id    = AvoidFeedIdCollision(MakeSafeId(feed_title));

            string feed_image_path = await DownloadFeedImageAsync(feed_id, parsed_feed.ImageUrl, feed_uri.Host);

            var feed = new Feed(feed_id, feed_url)
            {
                Title           = feed_title,
                Link            = $"{feed_uri.Scheme}://{feed_uri.Host}",
                ImagePath       = feed_image_path,
                DateLastUpdated = parsed_feed.LastUpdatedDate is null ? DateTime.Now : (DateTime)parsed_feed.LastUpdatedDate,
                Description     = ExtractTextFromHtml(parsed_feed.Description)
            };

            await WriteToFileAsync(Path.Combine(FeedDirectory, $"{feed_id}.feed"), feed.Serialize());

            Directory.CreateDirectory(Path.Combine(FeedDirectory, feed_id));

            await AddPostsToFeedAsync(feed, parsed_feed.Items);

            Feeds.Add(feed);
        }

        string AvoidFeedIdCollision(string id)
        {
            var pre_path = Path.Combine(FeedDirectory, id);

            if (Directory.Exists($"{pre_path}.feed"))
            {
                int suffix = 2;
                while (Directory.Exists($"{pre_path}_{suffix}.feed"))
                {
                    suffix++;
                }
                id = $"{id}_{suffix}";
            }
            return(id);
        }

        async Task <string> DownloadFeedImageAsync(string feed_id, string feed_image_url, string feed_host)
        {
            string feed_image_path = null;

            if (string.IsNullOrEmpty(feed_image_url))
            {
                try
                {
                    var web_client = new WebClient();
                    web_client.Headers.Add(HttpRequestHeader.UserAgent, "Fidd RSS Reader v1.0");
                    var favicon_api_response = await web_client.DownloadStringTaskAsync($"http://favicongrabber.com/api/grab/{feed_host}");

                    var deserialized_response = JsonConvert.DeserializeObject <FaviconGrabberResponse>(favicon_api_response);
                    if (deserialized_response.Icons.Count > 0)
                    {
                        feed_image_url = deserialized_response.Icons.First().Source;
                    }
                } catch (Exception e) {; }
            }
            if (!string.IsNullOrEmpty(feed_image_url))
            {
                if (feed_image_url.StartsWith("data:image/"))
                {
                    feed_image_url = feed_image_url.Substring(11);
                    var image_extension = feed_image_url.Substring(0, feed_image_url.IndexOf(';'));
                    feed_image_path = $"{feed_id}.{image_extension}";
                    var image_data_base64 = feed_image_url.Substring(feed_image_url.IndexOf(',') + 1);
                    await File.WriteAllBytesAsync(Path.Combine(FeedDirectory, feed_image_path), Convert.FromBase64String(image_data_base64));
                }
                else
                {
                    var    downloader      = new WebClient();
                    string image_extension = ExtractExtensionFromUrl(feed_image_url);
                    feed_image_path = $"{feed_id}{image_extension}";
                    await downloader.DownloadFileTaskAsync(feed_image_url, Path.Combine(FeedDirectory, feed_image_path));
                }
            }

            return(feed_image_path);
        }
    }