[blam/wcf: 1/8] Initial rough implementation of WCF



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]