/// <summary> /// Import subscription /// </summary> public void DoImport(IResource importRoot, bool addToWorkspace) { if (_login.Length == 0 || _password.Length == 0) { return; } RSSPlugin plugin = RSSPlugin.GetInstance(); string authInfo = Convert.ToBase64String(Encoding.ASCII.GetBytes(_login + ":" + _password)); ImportUtils.UpdateProgress(0, _progressMessage); importRoot = plugin.FindOrCreateGroup("Bloglines Subscriptions", importRoot); ImportUtils.UpdateProgress(10, _progressMessage); WebClient client = new WebClient(); client.Headers.Add("Authorization", "basic " + authInfo); ImportUtils.UpdateProgress(20, _progressMessage); try { Stream stream = client.OpenRead(_ImportURL); ImportUtils.UpdateProgress(30, _progressMessage); OPMLProcessor.Import(new StreamReader(stream), importRoot, addToWorkspace); ImportUtils.UpdateProgress(90, _progressMessage); } catch (Exception ex) { Trace.WriteLine("BlogLines subscrption load failed: '" + ex.Message + "'"); RemoveFeedsAndGroupsAction.DeleteFeedGroup(importRoot); string message = "Import of BlogLines subscription failed:\n" + ex.Message; if (ex is WebException) { WebException e = (WebException)ex; if (e.Status == WebExceptionStatus.ProtocolError && ((HttpWebResponse)e.Response).StatusCode == HttpStatusCode.Unauthorized) { message = "Import of BlogLines subscription failed:\nInvalid login or password."; } } ImportUtils.ReportError("BlogLines Subscription Import", message); } ImportUtils.UpdateProgress(100, _progressMessage); return; }
/// <summary> /// Import subscription /// </summary> public void DoImport(IResource importRoot, bool addToWorkspace) { importRoot = _plugin.FindOrCreateGroup("SharpReader subscriptions", importRoot); // We will add info about imported feeds here _importedFeeds = new ArrayList(); ImportUtils.UpdateProgress(0, _progressMessage); // Start to import feeds structure XmlDocument feedlist = new XmlDocument(); try { feedlist.Load(_subscriptionPath); } catch (Exception ex) { Trace.WriteLine("SharpReader subscrption load failed: '" + ex.Message + "'"); RemoveFeedsAndGroupsAction.DeleteFeedGroup(importRoot); ImportUtils.ReportError("SharpReader Subscription Import", "Import of SharpReader subscription failed:\n" + ex.Message); return; } ImportUtils.FeedUpdateData defaultUpdatePeriod; XmlAttribute period = feedlist.SelectSingleNode("/feeds/@refreshMinutes") as XmlAttribute; if (period != null) { defaultUpdatePeriod = ImportUtils.ConvertUpdatePeriod(period.Value, 1); } else { defaultUpdatePeriod = ImportUtils.ConvertUpdatePeriod("", 1); } ImportUtils.UpdateProgress(10, _progressMessage); XmlElement root = (XmlElement)feedlist.SelectSingleNode("/feeds"); ImportGroup(root, importRoot, defaultUpdatePeriod, addToWorkspace); ImportUtils.UpdateProgress(100, _progressMessage); return; }
private void ImportGroup(XmlElement root, IResource rootGroup, ImportUtils.FeedUpdateData defaultUpdatePeriod, bool addToWorkspace) { // Import all groups XmlNodeList l = root.SelectNodes("RssFeedsCategory"); if (l != null) { foreach (XmlElement group in l) { string name = group.GetAttribute("name"); if (name == null) { name = "Unknown group"; } IResource iGroup = _plugin.FindOrCreateGroup(name, rootGroup); ImportGroup(group, iGroup, defaultUpdatePeriod, addToWorkspace); } } // Import all elements IResource feedRes = null; l = root.SelectNodes("RssFeed"); if (l != null) { foreach (XmlElement feed in l) { string s = feed.GetAttribute("url"); if (s == null) { continue; } // May be, we are already subscribed? if (Core.ResourceStore.FindUniqueResource("RSSFeed", "URL", s) != null) { continue; } FeedInfo info = new FeedInfo(); info.url = s; // Ok, now we should create feed feedRes = Core.ResourceStore.NewResource("RSSFeed"); feedRes.BeginUpdate(); feedRes.SetProp("URL", s); ImportUtils.Attrib2Prop(feed, "name", feedRes, Core.Props.Name, Props.OriginalName); ImportUtils.Attrib2Prop(feed, "etag", feedRes, Props.ETag); ImportUtils.Attrib2Prop(feed, "authUserName", feedRes, Props.HttpUserName); s = feed.GetAttribute("authPassword"); if (s != null) { string sharpReaderPassword = "******"; MD5CryptoServiceProvider MD5 = new MD5CryptoServiceProvider(); TripleDESCryptoServiceProvider DES = new TripleDESCryptoServiceProvider(); DES.Key = MD5.ComputeHash(Encoding.ASCII.GetBytes(sharpReaderPassword)); DES.Mode = CipherMode.ECB; byte[] DESed = Convert.FromBase64String(s); byte[] DeDESed = DES.CreateDecryptor().TransformFinalBlock(DESed, 0, DESed.Length); // Huuray! feedRes.SetProp(Props.HttpPassword, Encoding.Unicode.GetString(DeDESed)); } s = feed.GetAttribute("lastRefresh"); if (s != null) { DateTime dt = DateTime.Parse(s); feedRes.SetProp(Props.LastUpdateTime, dt); } // Peridoically ImportUtils.FeedUpdateData upd; s = feed.GetAttribute("refreshMinutes"); if (s != null) { upd = ImportUtils.ConvertUpdatePeriod(s, 1); } else { upd = defaultUpdatePeriod; } feedRes.SetProp(Props.UpdatePeriod, upd.period); feedRes.SetProp(Props.UpdateFrequency, upd.freq); // Cached? info.cacheFile = GetCacheNameByURL(info.url); // Feed is ready feedRes.AddLink(Core.Props.Parent, rootGroup); feedRes.EndUpdate(); info.feed = feedRes; _importedFeeds.Add(info); if (addToWorkspace) { Core.WorkspaceManager.AddToActiveWorkspace(feedRes); } } } }
/// <summary> /// Import cached items, flags, etc. /// </summary> public void DoImportCache() { int totalFeeds = Math.Max(_importedFeeds.Count, 1); int processedFeeds = 0; // Import cache foreach (FeedInfo fi in _importedFeeds) { ImportUtils.UpdateProgress(processedFeeds / totalFeeds, _progressMessageCache); processedFeeds += 100; if (fi.feed.IsDeleted) { continue; } string path = Path.Combine(_cachePath, fi.cacheFile); if (!File.Exists(path)) { continue; } XmlDocument feed = new XmlDocument(); try { feed.Load(path); } catch (Exception ex) { Trace.WriteLine("SharpReader cache '" + path + "' load failed: '" + ex.Message + "'"); continue; } // Load info from feed string s = null; ImportUtils.InnerText2Prop(feed.SelectSingleNode("/rss/Description") as XmlElement, fi.feed, Props.Description); ImportUtils.InnerText2Prop(feed.SelectSingleNode("/rss/WebPageUrl") as XmlElement, fi.feed, Props.HomePage); ImportUtils.InnerText2Prop(feed.SelectSingleNode("/rss/Image/Title") as XmlElement, fi.feed, Props.ImageTitle); ImportUtils.InnerText2Prop(feed.SelectSingleNode("/rss/Image/Url") as XmlElement, fi.feed, Props.ImageURL); ImportUtils.InnerText2Prop(feed.SelectSingleNode("/rss/Image/Link") as XmlElement, fi.feed, Props.ImageLink); // Load items from feed FeedAuthorParser authParser = new FeedAuthorParser(); foreach (XmlElement item in feed.SelectNodes("/rss/Items")) { IResource feedItem = Core.ResourceStore.BeginNewResource("RSSItem"); ImportUtils.Child2Prop(item, "Title", feedItem, Core.Props.Subject); ImportUtils.Child2Prop(item, "Description", feedItem, Core.Props.LongBody); ImportUtils.Child2Prop(item, "Link", feedItem, Props.Link); ImportUtils.Child2Prop(item, "Guid", feedItem, Props.GUID); feedItem.SetProp(Core.Props.LongBodyIsHTML, true); ImportUtils.Child2Prop(item, "CommentsUrl", feedItem, Props.CommentURL); ImportUtils.Child2Prop(item, "CommentsRss", feedItem, Props.CommentRSS); ImportUtils.Child2Prop(item, "Subject", feedItem, Props.RSSCategory); s = ImportUtils.GetUniqueChildText(item, "CommentCount"); if (s != null) { try { feedItem.SetProp(Props.CommentCount, Int32.Parse(s)); } catch (FormatException) { Trace.WriteLine("SharpReader cache: invalid comment-count"); } catch (OverflowException) { Trace.WriteLine("SharpReader cache: invalid comment-count"); } } // Date s = ImportUtils.GetUniqueChildText(item, "PubDate"); if (s != null) { DateTime dt = DateTime.Parse(s); feedItem.SetProp(Core.Props.Date, dt); } // Read/unread s = ImportUtils.GetUniqueChildText(item, "IsRead"); if (s == null || s != "true") { feedItem.SetProp(Core.Props.IsUnread, true); } // Flag s = ImportUtils.GetUniqueChildText(item, "Flag"); if (s != null) { IResource flag = null; if (_flagsMap.ContainsKey(s)) { flag = (IResource)_flagsMap[s]; } else { flag = _defaultFlag; } feedItem.AddLink("Flag", flag); } // Author s = ImportUtils.GetUniqueChildText(item, "Author"); if (s != null) { authParser.ParseAuthorString(feedItem, s); } else { feedItem.AddLink(Core.ContactManager.Props.LinkFrom, fi.feed); } feedItem.EndUpdate(); fi.feed.AddLink(Props.RSSItem, feedItem); } } ImportUtils.UpdateProgress(processedFeeds / totalFeeds, _progressMessageCache); }
/// <summary> /// Import subscription /// </summary> public void DoImport(IResource importRoot, bool addToWorkspace) { if (null == FileNames) { return; } int totalFeeds = Math.Max(FileNames.Length, 1); int processedFeeds = 0; ImportUtils.UpdateProgress(processedFeeds / totalFeeds, _progressMessage); IResource currentRoot = null; foreach (string fileName in FileNames) { string defaultName = null; Stream opml = null; if (!File.Exists(fileName)) { defaultName = fileName; // Try to load as URL try { opml = new JetMemoryStream(new WebClient().DownloadData(fileName), true); } catch (Exception ex) { Trace.WriteLine("OPML file '" + fileName + "' can not be load: '" + ex.Message + "'"); opml = null; } } else { defaultName = Path.GetFileName(fileName); // Try to load title from this file try { opml = new FileStream(fileName, FileMode.Open, FileAccess.Read); } catch (Exception ex) { Trace.WriteLine("OPML file '" + fileName + "' can not be load: '" + ex.Message + "'"); opml = null; } } if (null == opml) { continue; } // Try to get name string name = null; try { XmlDocument xml = new XmlDocument(); xml.Load(opml); XmlElement title = xml.SelectSingleNode("/opml/head/title") as XmlElement; name = title.InnerText; } catch (Exception ex) { Trace.WriteLine("OPML file '" + fileName + "' doesn't have title: '" + ex.Message + "'"); } if (name == null || name.Length == 0) { name = defaultName; } try { opml.Seek(0, SeekOrigin.Begin); if (_manager == null || FileNames.Length > 1) { currentRoot = RSSPlugin.GetInstance().FindOrCreateGroup("Subscription from " + name, importRoot); } else { currentRoot = importRoot; } OPMLProcessor.Import(new StreamReader(opml), currentRoot, addToWorkspace); } catch (Exception ex) { Trace.WriteLine("OPML file '" + fileName + "' can not be load: '" + ex.Message + "'"); RemoveFeedsAndGroupsAction.DeleteFeedGroup(currentRoot); ImportUtils.ReportError("OPML File Import", "Import of OPML file '" + fileName + "' failed:\n" + ex.Message); } processedFeeds += 100; ImportUtils.UpdateProgress(processedFeeds / totalFeeds, _progressMessage); } return; }
/// <summary> /// Import cached items, flags, etc. /// </summary> public void DoImportCache() { Stream stream = null; RSSParser parser = null; // Register our item processor _plugin.RegisterItemElementParser(FeedType.Rss, _rbNS, "flag-status", this); _plugin.RegisterItemElementParser(FeedType.Atom, _rbNS, "flag-status", this); ImportUtils.UpdateProgress(0, _progressMessageCache); int totalFeeds = Math.Max(_importedFeeds.Count, 1); int processedFeeds = 0; // Ok, all feeds are created. Try to import all caches and mark read items _parseCache = true; foreach (FeedInfo fi in _importedFeeds) { ImportUtils.UpdateProgress(processedFeeds / totalFeeds, _progressMessageCache); processedFeeds += 100; if (fi.feed.IsDeleted) { continue; } if (null == fi.cacheFile) { continue; } string path = Path.Combine(_cachePath, fi.cacheFile); if (!File.Exists(path)) { continue; } try { // Load feed! parser = new RSSParser(fi.feed); using (stream = new FileStream(path, FileMode.Open, FileAccess.Read)) { parser.Parse(stream, Encoding.UTF8, true); } } catch (Exception ex) { Trace.WriteLine("RSS Bandit cache '" + path + "' load failed: '" + ex.Message + "'"); } if (fi.readItems != null) { // And mark as read IResourceList allItems = fi.feed.GetLinksTo("RSSItem", "From"); foreach (string readOne in fi.readItems) { IResourceList markAsRead = Core.ResourceStore.FindResources("RSSItem", "GUID", readOne).Intersect(allItems, true); foreach (IResource item in markAsRead) { item.DeleteProp(Core.Props.IsUnread); } } } } ImportUtils.UpdateProgress(processedFeeds / totalFeeds, _progressMessageCache); // And here we should import flags from flags stream if (_flaggedPath == null) { return; } // Register two additional elements _plugin.RegisterItemElementParser(FeedType.Rss, _rbNS, "feed-url", this); _plugin.RegisterItemElementParser(FeedType.Atom, _rbNS, "feed-url", this); _parseCache = false; IResource pseudoFeed = Core.ResourceStore.NewResourceTransient("RSSFeed"); try { parser = new RSSParser(pseudoFeed); parser.ItemParsed += this.FlaggedItemParsed; using (stream = new FileStream(_flaggedPath, FileMode.Open, FileAccess.Read)) { parser.Parse(stream, Encoding.UTF8, true); } } catch (Exception ex) { Trace.WriteLine("RssBandit flags load failed: '" + ex.Message + "'"); } pseudoFeed.Delete(); }
/// <summary> /// Import subscription /// </summary> public void DoImport(IResource importRoot, bool addToWorkspace) { IResource feedRes = null; importRoot = _plugin.FindOrCreateGroup("RssBandit subscriptions", importRoot); // We will add info about imported feeds here _importedFeeds = new ArrayList(); ImportUtils.UpdateProgress(0, _progressMessage); // Start to import feeds structure XmlDocument feedlist = new XmlDocument(); try { feedlist.Load(_subscriptionPath); } catch (Exception ex) { Trace.WriteLine("RssBandit subscrption load failed: '" + ex.Message + "'"); RemoveFeedsAndGroupsAction.DeleteFeedGroup(importRoot); ImportUtils.ReportError("RSS Bandit Subscription Import", "Import of RSS Bandit subscription failed:\n" + ex.Message); return; } ImportUtils.FeedUpdateData defaultUpdatePeriod; XmlAttribute period = feedlist.SelectSingleNode("/feeds/@refresh-rate") as XmlAttribute; if (period != null) { defaultUpdatePeriod = ImportUtils.ConvertUpdatePeriod(period.Value, 60000); } else { defaultUpdatePeriod = ImportUtils.ConvertUpdatePeriod("", 60000); } XmlNodeList feeds = feedlist.GetElementsByTagName("feed"); int totalFeeds = Math.Max(feeds.Count, 1); int processedFeeds = 0; ImportUtils.UpdateProgress(processedFeeds / totalFeeds, _progressMessage); foreach (XmlElement feed in feeds) { string s = ImportUtils.GetUniqueChildText(feed, "link"); if (s == null) { continue; } // May be, we are already subscribed? if (Core.ResourceStore.FindUniqueResource("RSSFeed", "URL", s) != null) { continue; } FeedInfo info = new FeedInfo(); info.url = s; IResource group = AddCategory(importRoot, feed.GetAttribute("category")); // Ok, now we should create feed feedRes = Core.ResourceStore.NewResource("RSSFeed"); feedRes.BeginUpdate(); feedRes.SetProp("URL", s); s = ImportUtils.GetUniqueChildText(feed, "title"); ImportUtils.Child2Prop(feed, "title", feedRes, Core.Props.Name, Props.OriginalName); ImportUtils.Child2Prop(feed, "etag", feedRes, Props.ETag); s = ImportUtils.GetUniqueChildText(feed, "last-retrieved"); if (s != null) { DateTime dt = DateTime.Parse(s); feedRes.SetProp("LastUpdateTime", dt); } // Peridoically ImportUtils.FeedUpdateData upd; s = ImportUtils.GetUniqueChildText(feed, "refresh-rate"); if (s != null) { upd = ImportUtils.ConvertUpdatePeriod(s, 60000); } else { upd = defaultUpdatePeriod; } feedRes.SetProp("UpdatePeriod", upd.period); feedRes.SetProp("UpdateFrequency", upd.freq); // Cached? s = ImportUtils.GetUniqueChildText(feed, "cacheurl"); if (s != null) { info.cacheFile = s; } else { info.cacheFile = null; } // Login & Password ImportUtils.Child2Prop(feed, "auth-user", feedRes, Props.HttpUserName); s = ImportUtils.GetUniqueChildText(feed, "auth-password"); if (s != null) { feedRes.SetProp(Props.HttpPassword, DecryptPassword(s)); } // Enclosures ImportUtils.Child2Prop(feed, "enclosure-folder", feedRes, Props.EnclosurePath); // Try to load "read" list XmlElement read = ImportUtils.GetUniqueChild(feed, "stories-recently-viewed"); if (read != null) { ArrayList list = new ArrayList(); foreach (XmlElement story in read.GetElementsByTagName("story")) { list.Add(story.InnerText); } if (list.Count > 0) { info.readItems = list; } else { info.readItems = null; } } // Feed is ready feedRes.AddLink(Core.Props.Parent, group); feedRes.EndUpdate(); info.feed = feedRes; _importedFeeds.Add(info); if (addToWorkspace) { Core.WorkspaceManager.AddToActiveWorkspace(feedRes); } processedFeeds += 100; ImportUtils.UpdateProgress(processedFeeds / totalFeeds, _progressMessage); } return; }
/// <summary> /// Import subscription /// </summary> public void DoImport(IResource importRoot, bool addToWorkspace) { RSSPlugin plugin = RSSPlugin.GetInstance(); importRoot = plugin.FindOrCreateGroup("FeedDemon subscriptions", importRoot); // Count full count of resources string[] allFiles = Directory.GetFiles(_groupsPath, "*.opml"); int totalFiles = Math.Max(allFiles.Length, 1); int processedFiles = 0; ImportUtils.UpdateProgress(processedFiles / totalFiles, _progressMessage); foreach (string file in allFiles) { IResource group = null; string name = Path.GetFileNameWithoutExtension(file); group = plugin.FindOrCreateGroup(name, importRoot); try { Hashtable ns = new Hashtable(); Stream stream = new FileStream(file, FileMode.Open, FileAccess.Read); // Fix bugs in OPML ns["fd"] = _fdNS; OPMLProcessor.Import(new StreamReader(stream), group, addToWorkspace, ns); } catch (Exception ex) { RemoveFeedsAndGroupsAction.DeleteFeedGroup(group); ImportUtils.ReportError("FeedDemon Subscription Import", "Import of FeedDemon group '" + name + "' failed:\n" + ex.Message); } processedFiles += 100; ImportUtils.UpdateProgress(processedFiles / totalFiles, _progressMessage); } // Read summary.xml string summary = Path.Combine(_channelsPath, "summary.xml"); if (File.Exists(summary)) { try { XmlDocument xdoc = new XmlDocument(); xdoc.Load(summary); foreach (XmlElement channel in xdoc.GetElementsByTagName("channel")) { string title = null; string url = null; XmlNodeList l = null; l = channel.GetElementsByTagName("title"); if (l.Count < 1) { continue; } title = l[0].InnerText; l = channel.GetElementsByTagName("newsFeed"); if (l.Count < 1) { continue; } url = l[0].InnerText; _name2url.Add(title, url); } } catch (Exception ex) { Trace.WriteLine("FeedDemon subscrption load failed: '" + ex.Message + "'"); } } return; }
/// <summary> /// Import cached items, flags, etc. /// </summary> public void DoImportCache() { RSSPlugin plugin = RSSPlugin.GetInstance(); _readItems = new ArrayList(); // Register us for special tags plugin.RegisterItemElementParser(FeedType.Rss, _fdNS, "state", this); plugin.RegisterItemElementParser(FeedType.Atom, _fdNS, "state", this); string[] allFiles = Directory.GetFiles(_channelsPath, "*.rss"); int totalFiles = Math.Max(allFiles.Length, 1); int processedFiles = 0; foreach (string file in allFiles) { ImportUtils.UpdateProgress(processedFiles / totalFiles, _progressMessageCache); processedFiles += 100; IResource feed = null; string name = HtmlTools.SafeHtmlDecode(Path.GetFileNameWithoutExtension(file)); if (_name2url.ContainsKey(name)) { IResourceList feeds = Core.ResourceStore.FindResources("RSSFeed", Props.URL, _name2url[name]); if (feeds.Count > 0) { feed = feeds[0]; } } if (feed == null) { IResourceList feeds = Core.ResourceStore.FindResources("RSSFeed", Core.Props.Name, name); if (feeds.Count > 0) { feed = feeds[0]; } } // Not found (import of this feed was canceled?) if (feed == null) { continue; } _readItems.Clear(); using (Stream rss = new FileStream(file, FileMode.Open)) { try { RSSParser parser = new RSSParser(feed); parser.Parse(rss, Encoding.UTF8, true); } catch (Exception ex) { Trace.WriteLine("FeedDemon cache '" + file + "' load failed: '" + ex.Message + "'"); } } foreach (IResource r in _readItems) { if (!r.IsDeleted) { r.DeleteProp(Core.Props.IsUnread); } } } ImportUtils.UpdateProgress(processedFiles / totalFiles, _progressMessageCache); }