2025-11-28 00:35:46 +09:00

280 lines
10 KiB
C#

// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) 2006 Microsoft Corporation. All rights reserved.
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Feeds.Interop;
using Microsoft.Samples.RssPlatform.ScreenSaver.Rss;
namespace Microsoft.Samples.RssPlatform.ScreenSaver
{
public class FeedList
{
private List<RssFeed> rssFeeds;
private int currentFeedIndex;
private int currentItemIndex;
private System.Drawing.Image currentImage;
private DateTime lastRefresh;
internal readonly static List<string> imageExtensions = new List<string>(
new string[] { "*.BMP", "*.GIF", "*.PNG", "*.JPG", "*.JPEG" });
public FeedList()
{
lastRefresh = DateTime.MinValue;
currentFeedIndex = -1;
currentItemIndex = -1;
}
public void Refresh()
{
if (lastRefresh == DateTime.MinValue)
{
// we never successfully loaded the CFL, so let's do it again
Load();
return;
}
IFeedsManager fs = new FeedsManager();
try
{
IFeedFolder folder = (IFeedFolder)fs.GetFolder(Properties.Settings.Default.ImagePathOverride);
foreach (IFeed feed in CommonFeedListUtils.LastWriteSince(folder, lastRefresh))
{
RssFeed rssFeed = null;
try
{
// This feed was updated or is new, let's get it.
rssFeed = RssFeed.FromApi(feed);
}
catch (System.Runtime.InteropServices.COMException ex)
{
System.Diagnostics.Debug.Print("Failed to get RSS feed '{0}' from API; skipping feed. Error: {1} ", feed.Name, ex.ToString());
continue; // Skip this feed.
}
// If the feed has no items with picture enclosures then skip it.
if (rssFeed == null || rssFeed.Items.Count == 0)
{
System.Diagnostics.Debug.Print("Feed '{0}' does not have any picture enclosures; skipping feed.", feed.Name);
continue;
}
// Before we add it let's see if we have an old version of the feed.
int index = rssFeeds.FindIndex(delegate(RssFeed f) { return (f.Path == rssFeed.Path); });
if (index == -1)
{
// This must be a new feed, let's append it to the list.
rssFeeds.Add(rssFeed);
}
else
{
// We have an existing feed with the same path. Let's insert it
// where the previous feed is at.
rssFeeds.Insert(index, rssFeed);
// Remove previous feed.
rssFeeds.RemoveAt(index + 1);
// Assure that current indexes are not out of bounds.
ValidateIndexes();
}
}
}
finally
{
GC.Collect(); // Release all COM objects and their file handles.
lastRefresh = DateTime.Now;
}
}
public void Load()
{
DateTime loadstart = DateTime.Now;
List<RssFeed> newRssFeeds = new List<RssFeed>();
try
{
IFeedsManager fs = new FeedsManager();
IFeedFolder folder = (IFeedFolder)fs.GetFolder(Properties.Settings.Default.ImagePathOverride);
foreach (IFeed feed in CommonFeedListUtils.CommonFeedList(folder))
{
System.Diagnostics.Debug.Print("Found feed {0} with {1} items.",
feed.Name, ((IFeedsEnum)feed.Items).Count);
try
{
RssFeed rssFeed = RssFeed.FromApi(feed);
// Only add this feed if it contains items
if (rssFeed != null)
{
System.Diagnostics.Debug.Print("Feed has {0} items with enclosures.", rssFeed.Items.Count);
if (rssFeed.Items.Count > 0)
newRssFeeds.Add(rssFeed);
}
else
System.Diagnostics.Debug.Print("Feed is null.");
}
catch (System.Runtime.InteropServices.COMException ex)
{
System.Diagnostics.Debug.Print("Failed to get RSS feed '{0}' from API; skipping feed. Error: {1} ", feed.Name, ex.ToString());
// Ignore exception, meaning ignore this feed and continue with next feed.
}
}
}
finally
{
// Collect garbage so that all the COM objects are released which
// closes the backing structured storage files.
GC.Collect();
}
if (newRssFeeds.Count == 0)
{
// There were no suitable feeds, hence get default feeds from resources.
System.Diagnostics.Debug.Print("There were no suitable feeds, hence get default feeds from resources.");
RssFeed rssFeed = RssFeed.FromText(Properties.Resources.DefaultRSSText);
newRssFeeds.Add(rssFeed);
}
this.rssFeeds = newRssFeeds;
// reset current indexes
currentFeedIndex = -1;
currentItemIndex = -1;
MoveNext();
lastRefresh = loadstart;
}
public int Count { get { return rssFeeds.Count; } }
public RssFeed GetFeed(int index)
{
return rssFeeds[index];
}
public RssFeed CurrentFeed { get { return rssFeeds[currentFeedIndex]; } }
public int CurrentFeedIndex { get { return currentFeedIndex; } }
public RssItem CurrentItem { get { return rssFeeds[currentFeedIndex].Items[currentItemIndex]; } }
public int CurrentItemIndex { get { return currentItemIndex; } }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "This method is time consuming since it accesses the file system.")]
public System.Drawing.Image CurrentImage
{
get
{
if (currentImage == null)
{
System.IO.FileInfo file = rssFeeds[currentFeedIndex].Items[currentItemIndex].Enclosure;
if (file != null)
{
// load from resource if resource url
if (ScreenSaverForm.IsResourcePictureFilename(file.Name))
{
switch (new Random().Next(2))
{
case 0:
currentImage = Properties.Resources.SSaverBackground;
break;
case 1:
currentImage = Properties.Resources.SSaverBackground2;
break;
}
}
else
{
// verify file's existence, else keep current image
file.Refresh();
if (file.Exists)
try
{
currentImage = System.Drawing.Image.FromFile(file.FullName);
}
catch (OutOfMemoryException)
{
// bad image file, let's skip it
currentImage = null;
}
}
}
}
return currentImage;
}
}
public void MoveNext()
{
if (rssFeeds == null || rssFeeds.Count == 0)
return;
// Clear the cached current image
currentImage = null;
// If we don't have a currentFeed then pick a feed and image
if (currentFeedIndex == -1)
{
// Pick random feed & image
//currentFeedIndex = new Random().Next(rssFeeds.Count);
//currentItemIndex = new Random().Next(rssFeeds[currentFeedIndex].Items.Count);
// Pick the first feed & image
currentFeedIndex = 0;
currentItemIndex = 0;
}
else
{
// Increment next item
currentItemIndex++;
ValidateIndexes();
}
}
public void MovePrevious()
{
if (rssFeeds == null || rssFeeds.Count == 0)
return;
// Clear the cached current image
currentImage = null;
currentItemIndex--;
if (currentItemIndex < 0)
{
// Return to the previous feed
currentFeedIndex--;
if (currentFeedIndex < 0)
currentFeedIndex = rssFeeds.Count - 1;
currentItemIndex = rssFeeds[currentFeedIndex].Items.Count - 1;
}
}
private void ValidateIndexes()
{
// If we are at the end of the feed jump to the next feed
if (currentItemIndex >= rssFeeds[currentFeedIndex].Items.Count)
{
currentItemIndex = 0;
// We also need to go to the next feed
currentFeedIndex++;
// If we are at the end of the feeds jump to the first feed
if (currentFeedIndex >= rssFeeds.Count)
{
currentFeedIndex = 0;
}
}
}
}
}