示例#1
0
 protected abstract void ProcessUpdatedMessage(ChatboxMessage message, bool isPartOfInitialSalvo = false, bool isEdited = false, bool isBanned = false);
示例#2
0
        /// <summary>
        /// Fetches new messages from the chatbox.
        /// </summary>
        /// <param name="retry">Level of desperation fetching the new messages.</param>
        protected void FetchNewMessages(int retry = 0)
        {
            string messagesResponse;

            try
            {
                messagesResponse = WebGetPage(MessagesUrl);
            }
            catch (WebException ex)
            {
                Logger.WarnFormat("fetching new messages failed, retry {0}\n{1}", retry, ex);

                // try harder
                Retry(retry, () => FetchNewMessages(retry + 1));
                return;
            }

            var messages = new HtmlDocument();

            messages.LoadHtml(messagesResponse);
            if (messages.DocumentNode == null)
            {
                // dang
                Retry(retry, () => FetchNewMessages(retry + 1));
                return;
            }

            var allTrs = messages.DocumentNode.SelectNodesOrEmpty("/tr");

            if (allTrs.Count == 0)
            {
                // aw crap
                Retry(retry, () => FetchNewMessages(retry + 1));
                return;
            }

            var newLastMessage       = _lastMessageReceived;
            var visibleMessageIDs    = new HashSet <long>();
            var newAndEditedMessages = new Stack <MessageToDistribute>();

            // for each message
            foreach (var tr in allTrs)
            {
                // pick out the TDs
                var tds = tr.SelectNodesOrEmpty("./td");
                if (tds.Count != 2)
                {
                    continue;
                }

                // pick out the first (metadata)
                var metaTd = tds[0];
                var bodyTd = tds[1];

                // find the link to the message and to the user
                var messageID = FishOutID(metaTd, MessageIDPiece);
                var userID    = FishOutID(metaTd, UserIDPiece);

                if (!messageID.HasValue || !userID.HasValue)
                {
                    // bah, humbug
                    continue;
                }

                if (newLastMessage < messageID.Value)
                {
                    newLastMessage = messageID.Value;
                }

                visibleMessageIDs.Add(messageID.Value);

                // fetch the timestamp
                var timestamp      = DateTime.Now;
                var timestampMatch = TimestampPattern.Match(metaTd.InnerHtml);
                if (timestampMatch.Success)
                {
                    var      timeString = timestampMatch.Groups[1].Value;
                    DateTime parsed;
                    if (DateTime.TryParseExact(
                            timeString,
                            "dd-MM-yy, HH:mm",
                            CultureInfo.InvariantCulture,
                            ForumConfig.UtcTime ? DateTimeStyles.AssumeUniversal : DateTimeStyles.AssumeLocal,
                            out parsed
                            ))
                    {
                        timestamp = parsed;
                    }
                }

                // get the nickname
                HtmlNode nickElement = null;
                foreach (var linkElement in metaTd.SelectNodesOrEmpty(".//a[@href]"))
                {
                    if (linkElement.GetAttributeValue("href", null).Contains(UserIDPiece))
                    {
                        nickElement = linkElement;
                    }
                }

                if (nickElement == null)
                {
                    // bah, humbug
                    continue;
                }

                var nick = nickElement.InnerText;

                var isBanned = ForumConfig.LowercaseBannedUsers.Contains(nick.ToLowerInvariant());

                // cache the nickname
                _lowercaseUsernamesToUserIDNamePairs[nick.ToLowerInvariant()] = new UserIDAndNickname(userID.Value, nick);

                var message = new ChatboxMessage(
                    messageID.Value,
                    userID.Value,
                    nickElement,
                    bodyTd,
                    timestamp,
                    Decompiler
                    );

                var body = bodyTd.InnerHtml;
                if (_oldMessageIDsToBodies.ContainsKey(messageID.Value))
                {
                    var oldBody = _oldMessageIDsToBodies[messageID.Value];
                    if (oldBody != body)
                    {
                        _oldMessageIDsToBodies[messageID.Value] = body;
                        newAndEditedMessages.Push(new MessageToDistribute(_initialSalvo, true, isBanned, message));
                    }
                }
                else
                {
                    _oldMessageIDsToBodies[messageID.Value] = body;
                    newAndEditedMessages.Push(new MessageToDistribute(_initialSalvo, false, isBanned, message));
                }
            }

            // port the bodies of messages that are still visible
            var messageIDsToBodies = new Dictionary <long, string>();

            foreach (var pair in _oldMessageIDsToBodies)
            {
                if (visibleMessageIDs.Contains(pair.Key))
                {
                    messageIDsToBodies[pair.Key] = pair.Value;
                }
            }
            _oldMessageIDsToBodies = messageIDsToBodies;

            // distribute the news and modifications
            while (newAndEditedMessages.Count > 0)
            {
                var msg = newAndEditedMessages.Pop();
                OnMessageUpdated(new MessageUpdatedEventArgs {
                    Message = msg
                });
            }

            _initialSalvo        = false;
            _lastMessageReceived = newLastMessage;
        }