[blam/wcf: 1/8] Initial rough implementation of WCF
- From: Carlos Martín Nieto <cmartin src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [blam/wcf: 1/8] Initial rough implementation of WCF
- Date: Mon, 6 Sep 2010 17:51:56 +0000 (UTC)
commit 8e178455bf762db603d42e1667f450f0544b16d1
Author: Carlos MartÃn Nieto <carlos cmartin tk>
Date: Wed Jun 2 20:02:08 2010 +0200
Initial rough implementation of WCF
Atom 1.0 feeds don't work, and not all informatino is taken
from the RSS 2.0 ones
src/Channel.cs | 47 ++++-------
src/FeedUpdater.cs | 245 +++++++++-------------------------------------------
src/Item.cs | 105 +++++++----------------
src/Makefile.am | 1 +
4 files changed, 88 insertions(+), 310 deletions(-)
---
diff --git a/src/Channel.cs b/src/Channel.cs
index c979597..08442a0 100644
--- a/src/Channel.cs
+++ b/src/Channel.cs
@@ -10,6 +10,7 @@ using System.Collections;
using System;
using System.Net;
using System.Xml.Serialization;
+using System.ServiceModel.Syndication;
namespace Imendio.Blam {
@@ -184,40 +185,24 @@ namespace Imendio.Blam {
}
}
- public bool UpdateItem (string id, RSSItem rssItem)
- {
- Item item = GetItem (id);
+ public bool UpdateItem(string id, SyndicationItem SyndItem)
+ {
+ Item item = GetItem(id);
- if (item == null) {
- item = new Item (id, rssItem);
- item.Channel = this;
- item.Unread = !Application.TheApp.CCollection.CheckItemIdReadInAllChannels(id);
+ if(item == null){
+ item = new Item(id, SyndItem);
- mItems.Add (item);
- return true;
- } else {
- bool updated = item.Update (rssItem);
- mUnupdatedItems.Remove (item);
- return updated;
- }
- }
+ item.Channel = this;
+ item.Unread = !Application.TheApp.CCollection.CheckItemIdReadInAllChannels(id);
+ mItems.Add(item);
- public bool UpdateItem (string id, AtomEntry entry)
- {
- Item item = GetItem (id);
-
- if (item == null) {
- item = new Item (id, entry);
- item.Channel = this;
-
- mItems.Add (item);
- return true;
- } else {
- bool updated = item.Update (entry);
- mUnupdatedItems.Remove (item);
- return updated;
- }
- }
+ return true;
+ } else {
+ bool updated = item.Update(SyndItem);
+ mUnupdatedItems.Remove(item);
+ return updated;
+ }
+ }
/* Used to cross-mark as read */
public void MarkItemIdAsRead (string id)
diff --git a/src/FeedUpdater.cs b/src/FeedUpdater.cs
index 231fb6b..bdab09e 100644
--- a/src/FeedUpdater.cs
+++ b/src/FeedUpdater.cs
@@ -12,6 +12,7 @@ using System.IO;
using System.Net;
using System.Xml;
using System.Xml.XPath;
+using System.ServiceModel.Syndication;
//using System.Web;
@@ -37,126 +38,51 @@ namespace Imendio.Blam {
}
}
public class FeedUpdater {
-
- private static string feed_type(ref string feed)
- {
- string type = null;
- try {
- XPathDocument doc = new XPathDocument(new StringReader(feed));
- XPathNavigator nav = doc.CreateNavigator();
- XmlNamespaceManager nsm = new XmlNamespaceManager(nav.NameTable);
- XPathExpression expr = nav.Compile("/atom03:feed|/atom10:feed|/rss10:RDF|/rss20:rss");
-
- nsm.AddNamespace("atom10", "http://www.w3.org/2005/Atom");
- nsm.AddNamespace("atom03", "http://purl.org/atom/ns#");
- nsm.AddNamespace("rss10", "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
- nsm.AddNamespace("rss20", "");
- expr.SetContext(nsm);
-
- XPathNodeIterator iter = nav.Select(expr);
- iter.MoveNext();
-
- if(iter.Current != null){
- switch(iter.Current.NamespaceURI){
- case "http://www.w3.org/2005/Atom":
- type = "Atom 1.0";
- break;
- case "http://purl.org/atom/ns#":
- type = "Atom 0.3";
- break;
- case "http://www.w3.org/1999/02/22-rdf-syntax-ns#":
- type = "RSS 1.0";
- break;
- case "":
- type = "RSS 2.0";
- break;
- default:
- type = "unknown";
- break;
- }
- } else {
- type = "unknown";
- }
- } catch(Exception e){
- Console.Error.WriteLine("Error determining feed type: {0}", e.Message);
- }
-
- return type;
- }
-
- public static bool Update (Channel channel)
- {
- channel.LastRefreshed = DateTime.Now;
- bool updated = false;
- WebResponse res = null;
- bool remote = true; /* Wether the feed is local or remote. */
- StreamReader stream = null;
- string feed = null;
-
- if(channel.Url.StartsWith("/") || channel.Url.StartsWith("file:")){
- remote = false;
- }
+ public static bool Update(Channel channel)
+ {
- if(remote){
- res = GetRemoteChannelData(channel);
+ bool updated = false;
- if(res == null){
- return false; /* Feed hasn't changed or we couldn't connect. */
+ channel.LastRefreshed = DateTime.Now;
+ XmlTextReader reader = null;
+ SyndicationFeed feed = null;
+ try{
+ System.Console.WriteLine("about to read {0}", channel.Url);
+ reader = new XmlTextReader(channel.Url);
+ if(reader == null){
+ System.Console.WriteLine("Can't init reader");
+ }
+ System.Console.WriteLine("xml reader done");
+ feed = SyndicationFeed.Load(reader);
+ } catch(XmlException e){
+ System.Console.WriteLine("Xml Ex caught: {0}", e.Message);
}
+ System.Console.WriteLine("loaded the feed!: {0}", feed.Title.Text);
+ channel.StartRefresh();
- stream = new StreamReader(res.GetResponseStream());
- feed = stream.ReadToEnd();
- stream.Close();
- } else {
- feed = GetLocalChannel(channel);
- if(feed == string.Empty){
- return false;
+ if ((channel.Name == "" || channel.Name == channel.Url) &&
+ feed.Title.Text != null) {
+ channel.Name = HtmlUtils.StripHtml(feed.Title.Text.Trim());
}
- }
- if(channel.Type == ""){
- string type = feed_type(ref feed);
-
- /* If we know for certain, assign it directly. */
- if(type == "Atom 0.3" || type == "Atom 1.0"){
- channel.Type = "Atom";
- } else if (type == "RSS 1.0" || type == "RSS 2.0"){
- channel.Type = "RSS";
- }
+ foreach(SyndicationItem item in feed.Items){
+ bool ItemUpdated = false;
+ string id = null;
- /* If it's still unknown, we don't speak it. */
- if(channel.Type == ""){
- return false;
- }
- }
+ id = GenerateItemId(item);
- try {
-
- if (channel.Type == "RSS") {
- updated = UpdateRssChannel(channel, ref feed);
- } else if (channel.Type == "Atom") {
- updated = UpdateAtomChannel(channel, ref feed);
- }
+ ItemUpdated = channel.UpdateItem(id, item);
- if(remote){
- if (res.Headers.Get("Last-Modified") != null) {
- channel.LastModified = res.Headers.Get("Last-Modified");
- }
- if (res.Headers.Get("ETag") != null) {
- channel.ETag = res.Headers.Get("ETag");
+ if(ItemUpdated){
+ updated = true;
}
-
- res.Close();
}
- } catch (Exception e) {
- Console.Error.WriteLine("Error whilst updating the feed {0}: {1}", channel.Name, e.Message);
- }
-
+ channel.FinishRefresh();
return updated;
- }
-
+ }
+
private static void set_credentials_from_uri(WebRequest req)
{
if (req.RequestUri.UserInfo != "") {
@@ -280,106 +206,15 @@ namespace Imendio.Blam {
return reader.ReadToEnd();
}
- private static bool UpdateRssChannel(Channel channel, ref string feed_content)
- {
- bool ChanUpdated = false;
- RSSFeed feed = RSSFeed.Load(new StringReader(feed_content));
-
- channel.StartRefresh();
-
- /* FIXME: Figure out how we should support multiple channels in one feed. */
-
- if((channel.Name == "" || channel.Name == channel.Url) &&
- feed.Channel[0].Title != null){
- channel.Name = HtmlUtils.StripHtml(feed.Channel[0].Title);
- ChanUpdated = true;
- }
-
- foreach (RSSItem item in feed.Channel[0].Item){
- string id = null;
- bool ItemUpdated = false;
-
- id = GenerateItemId(item);
-
- if(item.Title == null || item.Title == ""){
- if(item.Date != DateTime.MinValue){
- item.Title = item.Date.ToString("d MMM yyyy");
- } else {
- item.Title = feed.Channel[0].Title;
- }
- }
-
- ItemUpdated = channel.UpdateItem(id, item);
-
- if(ItemUpdated){
- ChanUpdated = true;
+ public static string GenerateItemId(SyndicationItem item)
+ {
+ if(item.Id != null){
+ return item.Id;
+ } else if(item.Links[0].Uri.ToString() != null){
+ return item.Links[0].Uri.ToString();
+ } else {
+ return item.Title.Text;
}
}
-
- channel.FinishRefresh();
-
- return ChanUpdated;
- }
-
- private static bool UpdateAtomChannel(Channel channel, ref string feed_content)
- {
- bool channelUpdated = false;
-
- try {
- AtomFeed feed = AtomFeed.Load(new StringReader(feed_content));
-
- if (feed != null) {
- channel.StartRefresh();
-
- if ((channel.Name == "" || channel.Name == channel.Url) &&
- feed.Title.Text != null) {
- channel.Name = HtmlUtils.StripHtml(feed.Title.Text.Trim());
- channelUpdated = true;
- }
-
- foreach (AtomEntry entry in feed.Entry) {
- string id;
- bool entryUpdated;
-
- id = GenerateItemId(entry);
- if (entry.Title.Text == "") {
- if (!entry.Modified.Equals(DateTime.MinValue)) {
- entry.Title.Text =
- entry.Modified.ToString("d MMM yyyy");
- } else {
- entry.Title.Text = channel.Name;
- }
- }
-
- entryUpdated = channel.UpdateItem (id, entry);
- if (entryUpdated) {
- channelUpdated = true;
- }
- }
-
- channel.FinishRefresh();
- }
- } catch (Exception) {
- }
-
- return channelUpdated;
- }
-
- public static string GenerateItemId (RSSItem item)
- {
- if (item.Guid != null) {
- return item.Guid;
- }
- else if (item.Link != null) {
- return item.Link;
- } else {
- return item.Title;
- }
- }
-
- public static string GenerateItemId (AtomEntry entry)
- {
- return entry.Id;
- }
}
}
diff --git a/src/Item.cs b/src/Item.cs
index ecd81a7..c3378a7 100644
--- a/src/Item.cs
+++ b/src/Item.cs
@@ -8,6 +8,7 @@ using RSS;
using Atom;
using System.Xml.Serialization;
using System;
+using System.ServiceModel.Syndication;
namespace Imendio.Blam {
public class Item {
@@ -45,86 +46,42 @@ namespace Imendio.Blam {
{
}
- public Item (string id, RSSItem rssItem)
- {
- this.Id = id;
- this.Title = HtmlUtils.StripHtml(rssItem.Title.Trim ());
-
- if(rssItem.Description != null){
- this.Text = rssItem.Description.Trim();
+ public Item(string id, SyndicationItem item)
+ {
+ this.Id = id;
+ if(item.Title.Text != null){
+ this.Title = HtmlUtils.StripHtml(item.Title.Text.Trim());
}
- if(rssItem.Content != null){
- this.Text = rssItem.Content.Trim();
+ if(item.Summary.Text != ""){
+ this.Text = item.Summary.Text.Trim();
}
- if (rssItem.Link != null) {
- this.Link = rssItem.Link.Trim();
- //} else if (rssItem.Guid != null && !rssItem.Guid.PermaLink.IsFalse) {
- // this.Link = rssItem.Guid.Name;
- } else {
- this.Link = "";
- }
-
- this.Author = rssItem.Author;
-
- this.PubDate = rssItem.Date;
- }
-
- public Item (string id, AtomEntry entry)
- {
- this.Id = id;
- this.Title = HtmlUtils.StripHtml(entry.Title.Text.Trim());
-
- if (entry.Author != null && entry.Author.Name != "") {
- this.Author = entry.Author.Name.Trim();
- }
-
- /* Content is optional in Atom feeds, or there may be multiple
- * contents of different media types. Use the summary if there
- * is no content, otherwise use HTML if it's available.
- */
- if (entry.Content == null || entry.Content.Length == 0) {
- Console.Error.WriteLine("no content, title= {0}", this.Title);
- if(entry.Summary.Text == null){
- Console.Error.WriteLine("summary text null");
- this.Text = "<p>There was no summary/content found for this entry. This is" +
- " most likely a bug.</p>";
- } else {
- this.Text = entry.Summary.Text.Trim();
- }
- } else {
- foreach (AtomText content in entry.Content) {
- if (content.Type == "text/html" ||
- content.Type == "html" ||
- content.Type == "application/xhtml+xml") {
- this.Text = content.Text.Trim();
- break;
- }
- }
- }
-
- /* Atom entries must have at least one link with a relationship
- * type of "alternate," but may have more. Again, prefer HTML if
- * more than one is available.
- */
- if (entry.Link.Length == 1) {
- this.Link = entry.Link[0].Url.Trim();
- } else {
- AtomLink link = entry.LinkByType("text/html");
- if(Link != null){
- this.Link = link.Url;
- } else {
- link = entry.LinkByType("application/xhtml+xml");
- if(link != null){
- this.Link = link.Url;
- }
- }
+ if(item.Content != null){
+ this.Text = (item.Content as TextSyndicationContent).Text;
+ }
- }
+ /* FIXME: Actually search for the "self" link */
+ if(item.Links[0].Uri.ToString() != ""){
+ this.Link = item.Links[0].Uri.ToString();
+ }
- this.PubDate = entry.Modified;
- }
+ //if(item.Authors.Size >= 1 && item.Authors[0] != null){
+ // this.Author = item.Authors[0].ToString();
+ //}
+ //TODO: Fix above and add this.PubDate
+ }
+
+ public bool Update(SyndicationItem SyndItem)
+ {
+ if(this.Title != HtmlUtils.StripHtml(SyndItem.Title.Text.Trim())){
+ this.Title = HtmlUtils.StripHtml(SyndItem.Title.Text.Trim());
+ this.SetUnread(true, true);
+ return true;
+ }
+ //TODO: Same as above with the content, and possibly add a changed state
+ return true;
+ }
/* This is called in the middle of an refresh so the channel will be
* updated when refresh is done
diff --git a/src/Makefile.am b/src/Makefile.am
index cfbb0bd..8f41898 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -10,6 +10,7 @@ RESOURCES = \
ASSEMBLIES = \
-r:System.Web \
-r:Mono.Posix \
+ -r:System.ServiceModel.Web \
-r:../lib/AtomFeed.dll \
-r:../lib/RSSFeed.dll
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]