예제 #1
0
 /// <summary>
 /// Creates protocol unit for posting article to server
 /// </summary>
 /// <param name="draftArticle"></param>
 /// <param name="server"></param>
 /// <param name="finishedMethod">can be null</param>
 public NntpPostArticleUnit(IResource draftArticle,
                            IResource server,
                            AsciiProtocolUnitDelegate finishedMethod,
                            bool invokedByUser)
 {
     _draftArticle  = draftArticle;
     _server        = new ServerResource(server);
     _invokedByUser = invokedByUser;
     _error         = "Failed to connect, posting abandoned.";
     if (finishedMethod != null)
     {
         Finished += finishedMethod;
     }
 }
예제 #2
0
 private static void ParseNewsgroups(IResource article, IResource groupRes, ServerResource serverRes, string newsgroups)
 {
     string[] groups = newsgroups.Split(',');
     foreach (string group in groups)
     {
         bool groupFound = false;
         foreach (IResource res in serverRes.Groups)
         {
             if (groupRes != res &&
                 String.Compare(group, res.GetPropText(Core.Props.Name), true) == 0 &&
                 new NewsgroupResource(res).IsSubscribed)
             {
                 article.AddLink(NntpPlugin._propTo, res);
                 groupFound = true;
                 break;
             }
         }
         if (!groupFound)
         {
             IResource     fakeGroup  = null;
             IResourceList fakeGroups = Core.ResourceStore.FindResources(
                 NntpPlugin._newsGroup, Core.Props.Name, group);
             if (fakeGroups.Count == 0)
             {
                 fakeGroup = Core.ResourceStore.NewResource(NntpPlugin._newsGroup);
                 fakeGroup.SetProp(Core.Props.Name, group);
             }
             else
             {
                 foreach (IResource res in fakeGroups)
                 {
                     if (fakeGroup == null || res.HasProp(Core.Props.Parent))
                     {
                         fakeGroup = res;
                         if (res.HasProp(Core.Props.Parent))
                         {
                             break;
                         }
                     }
                 }
             }
             article.AddLink(NntpPlugin._propTo, fakeGroup);
         }
     }
 }
예제 #3
0
 public NntpDownloadGroupsUnit(IResource server, bool refresh, JobPriority priority)
 {
     Interlocked.Increment(ref NntpPlugin._deliverNewsUnitCount);
     _serverResource = new ServerResource(server);
     Core.UIManager.GetStatusWriter(typeof(NntpDownloadGroupsUnit),
                                    StatusPane.Network).ShowStatus("Downloading groups from " + _serverResource.DisplayName + "...");
     _priority = priority;
     _nntpCmd  = "list";
     if (!refresh)
     {
         DateTime lastUpdated = _serverResource.LastUpdateTime;
         if (lastUpdated > DateTime.MinValue)
         {
             _nntpCmd = "newgroups " + ParseTools.NNTPDateString(lastUpdated);
         }
     }
     _count                  = 0;
     _responseChecked        = false;
     _groupList              = new ArrayList();
     _groupListLock          = new SpinWaitLock();
     _flushGroupListDelegate = new MethodInvoker(FlushGroupList);
 }
예제 #4
0
 public NntpConnection(ServerResource server)
     : base(server.Name, server.Port)
 {
     _server       = server;
     _serverProxy  = new ResourceProxy(server.Resource);
     this.Timeout  = Timeout = Core.SettingStore.ReadInt("NNTP", "Timeout", 60) * 1000;
     TraceProtocol = Settings.Trace;
     SSL3Enabled   = server.SSL3Enabled;
     _state        = NntpConnectionState.Connecting;
     System.Diagnostics.Trace.WriteLine(Server + ":" + Port + ": Connecting to server...");
     _serverProxy.DeletePropAsync(Core.Props.LastError);
     DoConnect();
     if (!_server.Resource.IsDeleted)
     {
         string username = _server.LoginName;
         if (username.Length > 0)
         {
             DoAuthenticate(username, _server.Password);
         }
         StartUnit(Int32.MaxValue, new AsciiSendLineGetLineUnit("mode reader"));
     }
 }
예제 #5
0
        public override void DisplayResource(IResource article, WordPtr[] wordsToHighlight)
        {
            if (_downloadLabel == null)
            {
                _downloadLabel               = new JetLinkLabel();
                _downloadLabel.Text          = "Click here or press F5 to download the article";
                _downloadLabel.BackColor     = Color.Transparent;
                _downloadLabel.ClickableLink = true;
                _downloadLabel.Click        += _downloadLabel_Click;
                Controls.Add(_downloadLabel);
            }
            _downloadLabel.Visible = false;
            _ieBrowser.Visible     = true;
            bool redisplayed = _articleIsRedisplayed;

            _articleIsRedisplayed = false;

            DisposeArticleListener();

            // Set the subject, highlight if needed
            ShowSubject(article.GetPropText(Core.Props.Subject), wordsToHighlight);

            try
            {
                //  The content being indexed (plaintext) is not the same that is
                //  displayed (autogenerated HTML), so the offsets are updated by
                //  this method to correspond to the new formatting.
                string sFormattedArticle = ArticleBody2Html(article, ref wordsToHighlight);
                ShowHtml(sFormattedArticle, _ctxRestricted, wordsToHighlight);
            }
            catch (Exception e)
            {
                Utils.DisplayException(e, "Error");
                return;
            }

            /**
             * set last selected article for article's owner
             */
            IResource owner = _rbrowser.OwnerResource;

            if (owner != null && (owner.Type == NntpPlugin._newsGroup ||
                                  owner.Type == NntpPlugin._newsFolder || owner.Type == NntpPlugin._newsServer))
            {
                ResourceProxy proxy = new ResourceProxy(owner);
                proxy.AsyncPriority = JobPriority.AboveNormal;
                proxy.SetPropAsync(NntpPlugin._propLastSelectedArticle, article.Id);
            }

            _articleListener = article.ToResourceListLive();
            _articleListener.ResourceChanged += _articleListener_ResourceChanged;

            bool hasNoBody = article.HasProp(NntpPlugin._propHasNoBody);

            if (!hasNoBody)
            {
                Core.UIManager.GetStatusWriter(this, StatusPane.Network).ClearStatus();
            }
            else
            {
                if (!Utils.IsNetworkConnectedLight())
                {
                    ShowHtml("<pre>" + NntpPlugin._networkUnavailable + ".</pre>", WebSecurityContext.Internet, null);
                    return;
                }
                IResourceList groups = article.GetLinksOfType(NntpPlugin._newsGroup, NntpPlugin._propTo);
                if (groups.Count > 0)
                {
                    foreach (IResource groupRes in groups.ValidResources)
                    {
                        IResource server = new NewsgroupResource(groupRes).Server;
                        if (server != null)
                        {
                            ServerResource serverRes = new ServerResource(server);
                            if (redisplayed || serverRes.DownloadBodiesOnDeliver || serverRes.DownloadBodyOnSelection)
                            {
                                Core.UIManager.GetStatusWriter(this, StatusPane.Network).ShowStatus("Downloading article...");
                                NntpConnection          articlesConnection = NntpConnectionPool.GetConnection(server, "foreground");
                                NntpDownloadArticleUnit downloadUnit       =
                                    new NntpDownloadArticleUnit(article, groupRes, JobPriority.Immediate, true);
                                downloadUnit.OnProgress += downloadUnit_OnProgress;
                                ShowHtml("<pre>Downloading article: 0%</pre>", WebSecurityContext.Internet, null);
                                articlesConnection.StartUnit(Int32.MaxValue - 1, downloadUnit);
                                return;
                            }
                        }
                    }
                    if (!redisplayed)
                    {
                        Point location = _ieBrowser.Location;
                        _downloadLabel.Location = new Point(location.X + 8, location.Y + 8);
                        _downloadLabel.Visible  = true;
                        _ieBrowser.Visible      = false;
                    }
                }
            }
        }
예제 #6
0
        /**
         * all article's processing should be performed in the resource thread
         * this function is called if article is downloaded from a group
         */
        public static void CreateArticle(string[] lines, IResource groupRes, string articleId)
        {
            // if user has already unsubscribed from the group or the
            // groups is already deleted then skip the article
            IResource server = new NewsgroupResource(groupRes).Server;

            if (server == null)
            {
                return;
            }

            articleId = ParseTools.EscapeCaseSensitiveString(articleId);
            // is article deleted?
            if (NewsArticleHelper.IsArticleDeleted(articleId))
            {
                return;
            }

            PrepareLines(lines);

            try
            {
                ServerResource serverRes   = new ServerResource(server);
                string         charset     = serverRes.Charset;
                bool           bodyStarted = false;
                string         line;
                string         content_type = string.Empty;
                string         content_transfer_encoding = string.Empty;
                IContact       sender = null;
                DateTime       date   = DateTime.MinValue;
                bool           mySelf = false;
                bool           newArticle;

                IResource article = Core.ResourceStore.FindUniqueResource(
                    NntpPlugin._newsArticle, NntpPlugin._propArticleId, articleId);
                if (article != null)
                {
                    if (!article.HasProp(NntpPlugin._propHasNoBody))
                    {
                        return;
                    }
                    article.BeginUpdate();
                    newArticle = false;
                }
                else
                {
                    article    = Core.ResourceStore.BeginNewResource(NntpPlugin._newsArticle);
                    newArticle = true;
                }

                for (int i = 0; i < lines.Length; ++i)
                {
                    line = lines[i];
                    if (line == null)
                    {
                        continue;
                    }
                    if (bodyStarted)
                    {
                        _bodyBuilder.Append(line);
                    }
                    else
                    {
                        _headersBuilder.Append(line);
                        _headersBuilder.Append("\r\n");
                        if (Utils.StartsWith(line, "from: ", true))
                        {
                            string from = line.Substring(6);
                            article.SetProp(NntpPlugin._propRawFrom, from);
                            mySelf = ParseFrom(article, TranslateHeader(charset, from), out sender);
                            UpdateLastCorrespondDate(sender, date);
                        }
                        else if (Utils.StartsWith(line, "subject: ", true))
                        {
                            string subject = line.Substring(9);
                            article.SetProp(NntpPlugin._propRawSubject, subject);
                            article.SetProp(Core.Props.Subject, TranslateHeader(charset, subject));
                        }
                        else if (Utils.StartsWith(line, "message-id: ", true))
                        {
                            ParseMessageId(article, ParseTools.EscapeCaseSensitiveString(line.Substring(12)), articleId);
                        }
                        else if (Utils.StartsWith(line, "newsgroups: ", true))
                        {
                            if (line.IndexOf(',') > 12)
                            {
                                ParseNewsgroups(article, groupRes, serverRes, line.Substring(12));
                            }
                        }
                        else if (Utils.StartsWith(line, "date: ", true))
                        {
                            date = ParseDate(article, line.Substring(6));
                            UpdateLastCorrespondDate(sender, date);
                        }
                        else if (Utils.StartsWith(line, "references: ", true))
                        {
                            ParseReferences(article, line.Substring(12));
                        }
                        else if (Utils.StartsWith(line, "content-type: ", true))
                        {
                            content_type = line.Substring(14);
                        }
                        else if (Utils.StartsWith(line, "followup-to: ", true))
                        {
                            article.SetProp(NntpPlugin._propFollowupTo, line.Substring(13));
                        }
                        else if (Utils.StartsWith(line, "content-transfer-encoding: ", true))
                        {
                            content_transfer_encoding = line.Substring(27);
                        }
                        else if (line == "\r\n")
                        {
                            bodyStarted = true;
                        }
                    }
                }
                ProcessBody(_bodyBuilder.ToString(), content_type, content_transfer_encoding, article, charset);
                article.SetProp(NntpPlugin._propArticleHeaders, _headersBuilder.ToString());
                article.AddLink(NntpPlugin._propTo, groupRes);
                if (article.GetPropText(NntpPlugin._propArticleId).Length == 0)
                {
                    article.SetProp(NntpPlugin._propArticleId, articleId);
                }
                if (newArticle)
                {
                    article.SetProp(NntpPlugin._propIsUnread, true);
                    IResourceList categories = Core.CategoryManager.GetResourceCategories(groupRes);
                    foreach (IResource category in categories)
                    {
                        Core.CategoryManager.AddResourceCategory(article, category);
                    }

                    Core.FilterEngine.ExecRules(StandardEvents.ResourceReceived, article);
                    CleanLocalArticle(articleId, article);
                }
                article.EndUpdate();

                CheckArticleInIgnoredThreads(article);
                CheckArticleInSelfThread(article);

                if (mySelf && serverRes.MarkFromMeAsRead)
                {
                    article.BeginUpdate();
                    article.DeleteProp(NntpPlugin._propIsUnread);
                    article.EndUpdate();
                }
                Core.TextIndexManager.QueryIndexing(article.Id);
            }
            finally
            {
                DisposeStringBuilders();
            }
        }
예제 #7
0
        public static void CreateArticleFromHeaders(string line, IResource groupRes)
        {
            string[] headers = line.Split('\t');
            if (headers.Length <= 5)
            {
                return;
            }
            string articleId = ParseTools.EscapeCaseSensitiveString(headers[4]);

            if (articleId.Length == 0 || NewsArticleHelper.IsArticleDeleted(articleId))
            {
                return;
            }
            // if user has already unsubscribed from the group or the
            // groups is already deleted then skip the article
            IResource server = new NewsgroupResource(groupRes).Server;

            if (server == null)
            {
                return;
            }

            // is article deleted?
            if (NewsArticleHelper.IsArticleDeleted(articleId))
            {
                return;
            }

            IResource article;
            IContact  sender;
            bool      mySelf;
            bool      newArticle;
            string    charset = new ServerResource(server).Charset;

            article = Core.ResourceStore.FindUniqueResource(
                NntpPlugin._newsArticle, NntpPlugin._propArticleId, articleId);
            if (article != null)
            {
                article.BeginUpdate();
                newArticle = false;
            }
            else
            {
                article    = Core.ResourceStore.BeginNewResource(NntpPlugin._newsArticle);
                newArticle = true;
            }
            article.SetProp(NntpPlugin._propHasNoBody, true);
            NewsArticleHelper.SetArticleNumber(article, groupRes, headers[0]);
            DateTime date = ParseDate(article, headers[3]);
            string   from = headers[2];

            article.SetProp(NntpPlugin._propRawFrom, from);
            mySelf = ParseFrom(article, TranslateHeader(charset, from), out sender);
            string subject = headers[1];

            article.SetProp(NntpPlugin._propRawSubject, subject);
            article.SetProp(Core.Props.Subject, TranslateHeader(charset, subject));
            UpdateLastCorrespondDate(sender, date);
            ParseMessageId(article, articleId, articleId);
            string references = headers[5];

            if (references.Length > 0)
            {
                ParseReferences(article, references);
            }
            article.AddLink(NntpPlugin._propTo, groupRes);
            if (newArticle)
            {
                article.SetProp(NntpPlugin._propIsUnread, true);
                IResourceList categories = Core.CategoryManager.GetResourceCategories(groupRes);
                foreach (IResource category in categories)
                {
                    Core.CategoryManager.AddResourceCategory(article, category);
                }
                Core.FilterEngine.ExecRules(StandardEvents.ResourceReceived, article);
                CleanLocalArticle(articleId, article);
            }
            article.EndUpdate();
            if (mySelf && new ServerResource(server).MarkFromMeAsRead)
            {
                article.BeginUpdate();
                article.DeleteProp(NntpPlugin._propIsUnread);
                article.EndUpdate();
            }
            Core.TextIndexManager.QueryIndexing(article.Id);
        }
예제 #8
0
        /**
         * this function is called if article is downloaded from a group
         * article should be a newly created transient resource
         */
        public static void CreateArticleByProtocolHandler(string[] lines, IResource article)
        {
            if (!article.IsTransient)
            {
                throw new ArgumentException("Article should be a newly created transient resource", "article");
            }

            string articleId = article.GetPropText(NntpPlugin._propArticleId);

            if (Core.ResourceStore.FindUniqueResource(
                    NntpPlugin._newsArticle, NntpPlugin._propArticleId, articleId) != null)
            {
                return;
            }

            PrepareLines(lines);

            try
            {
                IResource server      = article.GetLinkProp(NntpPlugin._propTo);
                string    charset     = new ServerResource(server).Charset;
                bool      bodyStarted = false;
                string    line;
                string    content_type = string.Empty;
                string    content_transfer_encoding = string.Empty;
                IContact  sender = null;
                DateTime  date   = DateTime.MinValue;
                bool      mySelf = false;

                for (int i = 0; i < lines.Length; ++i)
                {
                    line = lines[i];
                    if (line == null)
                    {
                        continue;
                    }
                    if (bodyStarted)
                    {
                        _bodyBuilder.Append(line);
                    }
                    else
                    {
                        _headersBuilder.Append(line);
                        _headersBuilder.Append("\r\n");
                        if (Utils.StartsWith(line, "from: ", true))
                        {
                            string from = line.Substring(6);
                            article.SetProp(NntpPlugin._propRawFrom, from);
                            mySelf = ParseFrom(article, TranslateHeader(charset, from), out sender);
                            UpdateLastCorrespondDate(sender, date);
                        }
                        else if (Utils.StartsWith(line, "subject: ", true))
                        {
                            string subject = line.Substring(9);
                            article.SetProp(NntpPlugin._propRawSubject, subject);
                            article.SetProp(Core.Props.Subject, TranslateHeader(charset, subject));
                        }
                        else if (Utils.StartsWith(line, "message-id: ", true))
                        {
                            ParseMessageId(article, ParseTools.EscapeCaseSensitiveString(line.Substring(12)), articleId);
                        }
                        else if (Utils.StartsWith(line, "newsgroups: ", true))
                        {
                            Subscribe2Groups(article, line.Substring(12));
                        }
                        else if (Utils.StartsWith(line, "date: ", true))
                        {
                            date = ParseDate(article, line.Substring(6));
                            UpdateLastCorrespondDate(sender, date);
                        }
                        else if (Utils.StartsWith(line, "references: ", true))
                        {
                            ParseReferences(article, line.Substring(12));
                        }
                        else if (Utils.StartsWith(line, "content-type: ", true))
                        {
                            content_type = line.Substring(14);
                        }
                        else if (Utils.StartsWith(line, "followup-to: ", true))
                        {
                            article.SetProp(NntpPlugin._propFollowupTo, line.Substring(13));
                        }
                        else if (Utils.StartsWith(line, "content-transfer-encoding: ", true))
                        {
                            content_transfer_encoding = line.Substring(27);
                        }
                        else if (line == "\r\n")
                        {
                            bodyStarted = true;
                        }
                    }
                }
                ProcessBody(_bodyBuilder.ToString(), content_type, content_transfer_encoding, article, charset);
                article.SetProp(NntpPlugin._propArticleHeaders, _headersBuilder.ToString());
                article.SetProp(NntpPlugin._propIsUnread, true);
                Core.FilterEngine.ExecRules(StandardEvents.ResourceReceived, article);
                CleanLocalArticle(articleId, article);
                article.EndUpdate();
                if (mySelf && new ServerResource(server).MarkFromMeAsRead)
                {
                    article.BeginUpdate();
                    article.DeleteProp(NntpPlugin._propIsUnread);
                    article.EndUpdate();
                }
                Core.TextIndexManager.QueryIndexing(article.Id);
            }
            finally
            {
                DisposeStringBuilders();
            }
        }
예제 #9
0
        public static void DeliverNewsFromServer(IResource server,
                                                 IResource preferableGroup,
                                                 bool invokedByUser,
                                                 AsciiProtocolUnitDelegate finishedMethod)
        {
            Guard.NullArgument(server, "server");

            ServerResource serverResource = new ServerResource(server);

            if (Utils.IsNetworkConnectedLight())
            {
                NntpConnection connection = NntpConnectionPool.GetConnection(server, "background");
                IResourceList  groups     = serverResource.Groups;

                if (groups.Count > 0)
                {
                    /**
                     * at first deliver news from prefered group
                     */
                    if (preferableGroup != null && groups.Contains(preferableGroup))
                    {
                        connection.StartUnit(Int32.MaxValue - 2,
                                             new NntpDownloadHeadersUnit(new NewsgroupResource(preferableGroup), JobPriority.AboveNormal));
                        if (serverResource.DownloadBodiesOnDeliver)
                        {
                            connection.StartUnit(Int32.MaxValue - 3,
                                                 new NntpDeliverEmptyArticlesFromGroupsUnit(preferableGroup.ToResourceList(), null));
                        }
                    }

                    /**
                     * then deliver headers of other groups
                     */
                    NntpDeliverHeadersFromGroupsUnit deliverHeadersFromGroupsUnit =
                        new NntpDeliverHeadersFromGroupsUnit(groups, preferableGroup);
                    if (finishedMethod != null)
                    {
                        deliverHeadersFromGroupsUnit.Finished += finishedMethod;
                    }
                    int clientPriority = 0;
                    if (invokedByUser && preferableGroup != null && groups.Contains(preferableGroup))
                    {
                        clientPriority = Int32.MaxValue - 3;
                    }
                    connection.StartUnit(clientPriority, deliverHeadersFromGroupsUnit);

                    /**
                     * then download empty bodies
                     */
                    if (serverResource.DownloadBodiesOnDeliver)
                    {
                        NntpDeliverEmptyArticlesFromGroupsUnit deliverEmptyArticlesUnit =
                            new NntpDeliverEmptyArticlesFromGroupsUnit(groups, preferableGroup);
                        if (finishedMethod != null)
                        {
                            deliverEmptyArticlesUnit.Finished += finishedMethod;
                        }
                        connection.StartUnit(clientPriority, deliverEmptyArticlesUnit);
                    }
                }

                /**
                 * finally replicate new groups
                 */
                NntpDownloadGroupsUnit groupsUnit = new NntpDownloadGroupsUnit(server, false, JobPriority.Lowest);
                if (finishedMethod != null)
                {
                    groupsUnit.Finished += finishedMethod;
                }
                connection.StartUnit(0, groupsUnit);
            }

            /**
             * queue timed news delivering is necessary
             */
            int freq = serverResource.DeliverFreq;

            if (freq > 0)
            {
                Core.NetworkAP.QueueJobAt(
                    DateTime.Now.AddMinutes(freq), new ResourceDelegate(DeliverNewsFromServer), server);
            }
        }