1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
/* RssFeedAction.cs
*
* GNOME Do is the legal property of its developers. Please refer to the
* COPYRIGHT file distributed with this
* source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
using Do.Universe;
using Rss;
namespace Do.Plugins.Rss
{
public class RssFeedAction : Act
{
private Dictionary<string, CachedFeed> cachedFeeds
= new Dictionary<string, CachedFeed>();
public override string Name {
get { return "RSS feed"; }
}
public override string Description {
get { return "View RSS feed contents"; }
}
public override string Icon { get { return "feed-icon.png@" + GetType ().Assembly.FullName; } }
public override IEnumerable<Type> SupportedItemTypes {
get {
return new Type[] {
typeof (RssFeedItem)
};
}
}
public override IEnumerable<Item> Perform (IEnumerable<Item> items, IEnumerable<Item> modifierItems)
{
List<Item> rssItems = new List<Item> ();
string url = (items.First () as RssFeedItem).URL;
RssFeed feed;
if (cachedFeeds.ContainsKey (url)) {
CachedFeed cachedFeed = cachedFeeds[url];
if (cachedFeed.Expiry < DateTime.Now) {
// Only fetch the feed if it's been modified since it
// was last read.
feed = RssFeed.Read (cachedFeeds[url].RssFeed,
RssItemSource.Timeout);
}
else {
// use the locally cached results
feed = cachedFeed.RssFeed;
}
}
else {
// This feed hasn't been requested yet.
// Fetch the feed and add it to the cache.
feed = RssFeed.Read (url, RssItemSource.Timeout);
CachedFeed cachedFeed = new CachedFeed ();
cachedFeed.Expiry = DateTime.Now.AddMinutes
(RssItemSource.CacheDuration);
cachedFeed.RssFeed = feed;
// Add the feed to the cache
cachedFeeds.Add (url, cachedFeed);
}
if (feed.Channels.Count > 0) {
foreach (RssItem rssItem in feed.Channels[0].Items) {
string title = TidyHtml (rssItem.Title);
string description = TidyHtml (rssItem.Description);
RssFeedLinkItem linkItem =
new RssFeedLinkItem (title, rssItem.Link.ToString(),
description);
rssItems.Add (linkItem);
}
}
return rssItems.ToArray();
}
/// <summary>
/// Strips HTML, newlines and replaces HTML entities
/// </summary>
/// <param name="input">
/// A <see cref="System.String"/>
/// </param>
/// <returns>
/// Processed output <see cref="System.String"/>
/// </returns>
protected string TidyHtml (string input)
{
string output = Regex.Replace (input, @"<(.|\n)*?>",string.Empty);
// Having more than 60 chars can cause Do's window to grow too big
if (output.Length > 60) {
output = output.Remove (60);
}
output = output.Replace (Environment.NewLine, string.Empty);
// replace entities
output = HttpUtility.HtmlDecode (output);
return output;
}
}
/// <summary>
/// Class used to cache Rss feeds locally.
/// RSS.NET uses the last modified header to only pull
/// the feed if it's been modified since the last request,
/// but this still requires sending a HttpWebRequest
/// which slows Do down somewhat.
/// </summary>
public class CachedFeed
{
private DateTime expiry;
private RssFeed rssFeed;
public DateTime Expiry {
get { return expiry; }
set { expiry = value; }
}
public RssFeed RssFeed {
get { return rssFeed; }
set { rssFeed = value; }
}
}
}
|