Пример #1
0
        private void ParseNextCandidate()
        {
            PriorityQueue.QueueEntry qEntry = _candidateURLs.PopEntry();
            if (qEntry == null)
            {
                OnDiscoverDone();
                return;
            }
            if (_lastPriority != -1 && qEntry.Priority != _lastPriority && qEntry.Priority < 9 && _results.Count > 0)
            {
                OnDiscoverDone();
                return;
            }

            _lastPriority = qEntry.Priority;

            ResourceProxy newFeedProxy = ResourceProxy.BeginNewResource("RSSFeed");

            newFeedProxy.SetProp("Transient", 1);
            newFeedProxy.SetProp("URL", (string)qEntry.Value);
            newFeedProxy.EndUpdate();
            _lastFeed = newFeedProxy.Resource;

            _lastUnitOfWork = new RSSUnitOfWork(_lastFeed, false, true);
            _lastUnitOfWork.DownloadProgress += new DownloadProgressEventHandler(RSSDownloadProgress);
            _lastUnitOfWork.ParseDone        += new EventHandler(RSSParseDone);
            Core.NetworkAP.QueueJob(_lastUnitOfWork);
        }
Пример #2
0
        public override AbstractJob GetNextJob()
        {
            RSSUnitOfWork nextJob = null;

            if (_currentFeed != _feedUrls.Length)
            {
                string status = "Processing: " + _feedNames[_currentFeed];
                Trace.WriteLine("MultipleFeedsJob -- Processing: " + _feedNames[_currentFeed]);
                if (DownloadTitleProgress != null)
                {
                    DownloadTitleProgress(this, new DownloadProgressEventArgs(status));
                }

                ResourceProxy proxy = ResourceProxy.BeginNewResource("RSSFeed");
                proxy.SetProp(Props.Transient, 1);
                proxy.SetProp(Props.URL, _feedUrls[_currentFeed] + _query);
                proxy.SetProp(Props.RSSSearchPhrase, _searchPhrase);
                proxy.SetProp(Core.Props.Name, _feedNames[_currentFeed++] + ": \"" + _query + "\"");
                proxy.EndUpdate();
                _feedProxies.Add(proxy);

                nextJob = new RSSUnitOfWork(proxy.Resource, false, true);
                nextJob.DownloadProgress += DownloadProgress;
                nextJob.ParseDone        += JobParseDone;
            }
            return(nextJob);
        }
Пример #3
0
        public static void CleanupCommentFeed(RSSUnitOfWork uow)
        {
            IResource commentItem = uow.Feed.GetLinkProp(Props.ItemCommentFeed);

            if (commentItem == null)
            {
                return;
            }
            IResourceList comments     = commentItem.GetLinksTo("RSSItem", Props.ItemComment);
            int           commentCount = comments.Count;

            foreach (IResource existingComment in comments)
            {
                if (existingComment.HasProp(Props.Transient))
                {
                    --commentCount;
                    new ResourceProxy(existingComment).Delete();
                }
                else if (commentItem.HasProp(Core.Props.IsDeleted))
                {
                    new ResourceProxy(existingComment).SetProp(Core.Props.IsDeleted, true);
                }
            }
            new ResourceProxy(commentItem).SetProp(Props.CommentCount, commentCount);
            new ResourceProxy(uow.Feed).DeleteProp(Props.UpdateStatus);
        }
Пример #4
0
 public override bool Equals(object obj)
 {
     if (obj is RSSUnitOfWork)
     {
         RSSUnitOfWork job = (RSSUnitOfWork)obj;
         return(_feed.Id == job._feed.Id);
     }
     return(false);
 }
Пример #5
0
        private void QueueFeedUpdate(IResource feed, int attempt, JobPriority jobPriority)
        {
            if (feed.Type != "RSSFeed")
            {
                throw new ArgumentException("Invalid resource type for QueueFeedUpdate: " + feed.Type);
            }

            if (!HttpReader.IsSupportedProtocol(feed.GetPropText(Props.URL)))
            {
                return;
            }

            //  Do not update feeds which were manually set into
            //  hybernating state.
            if (feed.HasProp(Props.IsPaused))
            {
                return;
            }

            lock (this)
            {
                if (_updatingCount >= _maxCount)
                {
                    _pendingFeeds.Push((int)jobPriority, new PendingFeed(feed, attempt));
                }
                else
                {
                    RSSUnitOfWork uow = new RSSUnitOfWork(feed, true, false);
                    uow.Attempts   = attempt;
                    uow.ParseDone += new EventHandler(OnRSSParseDone);
                    Core.NetworkAP.QueueJob(jobPriority, uow);
                    _updatingCount++;
                }
            }
            if (feed.HasProp(Props.AutoUpdateComments))
            {
                foreach (IResource commentFeed in feed.GetLinksTo(null, Props.FeedComment2Feed))
                {
                    if (NeedUpdate(commentFeed))
                    {
                        QueueFeedUpdate(commentFeed);
                    }
                }
            }
        }
Пример #6
0
        private void  JobParseDone(object sender, EventArgs e)
        {
            RSSUnitOfWork job = (RSSUnitOfWork)sender;

            if (job.Status != RSSWorkStatus.Success)
            {
                Trace.WriteLine("MultipleFeedsJob -- JobParseDone failed with code " + _currStatus);

                _failedFeeds.Add(job.Feed);
                _lastException = job.LastException;
            }

            //  Update status if only previous iterations were successful.
            //  Otherwise keep the fact that an error has already occured.
            //  This is necessary in the case when some is parsed correctly
            //  after the errorneous one.
            if (_currStatus == RSSWorkStatus.Success)
            {
                _currStatus = job.Status;
            }
        }
Пример #7
0
        private void RSSDownloadProgress(object sender, DownloadProgressEventArgs e)
        {
            RSSUnitOfWork uow = (RSSUnitOfWork)sender;

            OnDiscoverProgress("Trying " + uow.FeedURL + " (" + e.SizesToString() + ")...");
        }
Пример #8
0
        private void OnRSSParseDone(object sender, EventArgs e)
        {
            RSSUnitOfWork uow = (RSSUnitOfWork)sender;

            uow.ParseDone -= new EventHandler(OnRSSParseDone);

            if (uow.Status == RSSWorkStatus.FeedDeleted)
            {
                return;
            }

            ResourceProxy proxy = new ResourceProxy(uow.Feed);

            proxy.BeginUpdate();
            proxy.SetProp(Props.LastUpdateTime, DateTime.Now);
            if (!uow.Feed.HasProp(Core.Props.Parent) && !uow.Feed.HasProp(Props.ItemCommentFeed))
            {
                proxy.SetProp(Core.Props.Parent, RSSPlugin.RootFeedGroup);
            }
            if (uow.Status == RSSWorkStatus.HTTPError || uow.Status == RSSWorkStatus.XMLError)
            {
                proxy.SetProp(Props.UpdateStatus, "(error)");
                proxy.SetProp(Core.Props.LastError, uow.LastException.Message);
            }
            else
            {
                proxy.DeleteProp(Props.UpdateStatus);
                proxy.DeleteProp(Core.Props.LastError);
            }
            if (uow.LastException is HttpDecompressException)
            {
                proxy.SetProp(Props.DisableCompression, true);
            }

            if (uow.Status == RSSWorkStatus.HTTPError && uow.HttpStatus == HttpStatusCode.Gone)
            {
                proxy.SetProp(Props.UpdateFrequency, -1);
            }
            else if (!uow.Feed.HasProp(Props.UpdateFrequency))
            {
                proxy.SetProp(Props.UpdateFrequency, (int)Settings.UpdateFrequency);
            }
            if (!uow.Feed.HasProp(Props.UpdatePeriod))
            {
                proxy.SetProp(Props.UpdatePeriod, (string)Settings.UpdatePeriod);
            }

            proxy.EndUpdate();

            if (uow.Status == RSSWorkStatus.HTTPError && uow.Attempts < 3)
            {
                Core.NetworkAP.QueueJobAt(
                    DateTime.Now.AddMinutes(5),
                    new QueueFeedUpdateDelegate(QueueFeedUpdate), uow.Feed, uow.Attempts + 1);
            }

            if (uow.Status == RSSWorkStatus.Success && uow.Feed.HasProp(Props.AutoDownloadEnclosure))
            {
                ScheduleEnclosures(uow.Feed);
            }

            CleanupCommentFeed(uow);
            ScheduleFeedUpdate(uow.Feed);

            if (FeedUpdated != null)
            {
                FeedUpdated(this, new ResourceEventArgs(uow.Feed));
            }

            lock (this)
            {
                _updatingCount--;
                while (_pendingFeeds.Count > 0)
                {
                    PendingFeed feed = (PendingFeed)_pendingFeeds.Pop();
                    if (feed.Feed.IsDeleted)
                    {
                        continue;
                    }
                    QueueFeedUpdate(feed.Feed, feed.Attempt);
                    break;
                }
                // Has queue gotten empty?
                if ((_pendingFeeds.Count == 0) && (_updatingCount == 0))
                {
                    Core.UserInterfaceAP.QueueJob("Feeds Update Queue has Gotten Empty.", new MethodInvoker(FireQueueGotEmpty));
                }
            }
        }