예제 #1
0
        /// <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;
        }
예제 #2
0
        /// <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;
        }
예제 #3
0
        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);
                    }
                }
            }
        }
예제 #4
0
        /// <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);
        }
예제 #5
0
파일: OPMLImporter.cs 프로젝트: mo5h/omeo
        /// <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;
        }
예제 #6
0
        /// <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();
        }
예제 #7
0
        /// <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;
        }
예제 #8
0
        /// <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;
        }
예제 #9
0
        /// <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);
        }