Beispiel #1
0
        public void ParseBBC(InputModels.ProcessedMessageInput processedMessageInput)
        {
            // NOTE:
            // If you do not want to encumber your software with the CodeKicker library, start with replacing this call.

            processedMessageInput.DisplayBody = BBCParser.ToHtml(processedMessageInput.DisplayBody);
        }
Beispiel #2
0
        public async Task <InputModels.ProcessedMessageInput> ProcessMessageInput(ServiceModels.ServiceResponse serviceResponse, string messageBody)
        {
            InputModels.ProcessedMessageInput processedMessage = null;

            try {
                processedMessage = PreProcessMessageInput(messageBody);
                PreProcessSmileys(processedMessage);
                ParseBBC(processedMessage);
                ProcessSmileys(processedMessage);
                await ProcessMessageBodyUrls(processedMessage);

                FindMentionedUsers(processedMessage);
                PostProcessMessageInput(processedMessage);
            }
            catch (ArgumentException e) {
                serviceResponse.Error(nameof(InputModels.MessageInput.Body), $"An error occurred while processing the message. {e.Message}");
            }

            if (processedMessage is null)
            {
                serviceResponse.Error(nameof(InputModels.MessageInput.Body), $"An error occurred while processing the message.");
                return(processedMessage);
            }

            return(processedMessage);
        }
        public async Task <InputModels.ProcessedMessageInput> ProcessMessageInput(string messageBody)
        {
            var processedMessage = new InputModels.ProcessedMessageInput {
                OriginalBody   = messageBody ?? string.Empty,
                DisplayBody    = messageBody ?? string.Empty,
                MentionedUsers = new List <string>()
            };

            try {
                processedMessage = await PreProcess(processedMessage);
                await ProcessSmileys(processedMessage);
                await ProcessMessageBodyUrls(processedMessage);
                await FindMentionedUsers(processedMessage);

                PostProcessMessageInput(processedMessage);
            }
            catch (ArgumentException ex) {
                processedMessage.Errors.Add("Body", $"An error occurred while processing the message. {ex.Message}");
            }

            if (processedMessage is null)
            {
                processedMessage.Errors.Add("Body", $"An error occurred while processing the message.");
                return(processedMessage);
            }

            return(processedMessage);
        }
		/// <summary>
		/// Searches a post for references to other users
		/// </summary>
		public async Task FindMentionedUsers(InputModels.ProcessedMessageInput processedMessageInput) {
			var regexUsers = new Regex(@"@(\S+)");

			var matches = 0;

			foreach (Match regexMatch in regexUsers.Matches(processedMessageInput.DisplayBody)) {
				matches++;

				// DoS prevention
				if (matches > 10) {
					break;
				}

				var matchedTag = regexMatch.Groups[1].Value;

				var users = await AccountRepository.Records();

				var user = users.FirstOrDefault(u => u.DisplayName.ToLower() == matchedTag.ToLower());

				// try to guess what they meant
				if (user is null) {
					user = users.FirstOrDefault(u => u.UserName.ToLower().Contains(matchedTag.ToLower()));
				}

				if (user != null) {
					if (user.Id != UserContext.ApplicationUser.Id) {
						processedMessageInput.MentionedUsers.Add(user.Id);
					}

					// Eventually link to user profiles
					// returnObject.ProcessedBody = Regex.Replace(returnObject.ProcessedBody, @"@" + regexMatch.Groups[1].Value, "<a href='/Profile/Details/" + user.UserId + "' class='user'>" + user.DisplayName + "</span>");
				}
			}
		}
Beispiel #5
0
        /// <summary>
        /// Attempt to replace URLs in the message body with something better
        /// </summary>
        public async Task ProcessMessageBodyUrls(InputModels.ProcessedMessageInput processedMessageInput)
        {
            var displayBody = processedMessageInput.DisplayBody;

            var regexUrl = new Regex("(^| )((https?\\://){1}\\S+)", RegexOptions.Compiled | RegexOptions.Multiline);

            var matches = 0;

            foreach (Match regexMatch in regexUrl.Matches(displayBody))
            {
                matches++;

                // DoS prevention
                if (matches > 10)
                {
                    break;
                }

                var siteUrl = regexMatch.Groups[2].Value;

                if (!string.IsNullOrEmpty(siteUrl))
                {
                    var remoteUrlReplacement = await GetRemoteUrlReplacement(siteUrl);

                    displayBody = remoteUrlReplacement.Regex.Replace(displayBody, remoteUrlReplacement.ReplacementText, 1);

                    processedMessageInput.Cards += remoteUrlReplacement.Card;
                }
            }

            processedMessageInput.DisplayBody = displayBody;
        }
Beispiel #6
0
 public void PreProcessSmileys(InputModels.ProcessedMessageInput processedMessageInput)
 {
     for (var i = 0; i < SmileyRepository.Count(); i++)
     {
         var pattern     = @"(^|[\r\n\s])" + Regex.Escape(SmileyRepository[i].Code) + @"(?=$|[\r\n\s])";
         var replacement = $"$1SMILEY_{i}_INDEX";
         processedMessageInput.DisplayBody = Regex.Replace(processedMessageInput.DisplayBody, pattern, replacement, RegexOptions.Singleline);
     }
 }
Beispiel #7
0
 public void ProcessSmileys(InputModels.ProcessedMessageInput processedMessageInput)
 {
     for (var i = 0; i < SmileyRepository.Count(); i++)
     {
         var pattern     = $@"SMILEY_{i}_INDEX";
         var replacement = "<img src='" + SmileyRepository[i].Path + "' />";
         processedMessageInput.DisplayBody = Regex.Replace(processedMessageInput.DisplayBody, pattern, replacement);
     }
 }
		public async Task ProcessSmileys(InputModels.ProcessedMessageInput processedMessageInput) {
			var smileys = await SmileyRepository.Records();

			for (var i = 0; i < smileys.Count(); i++) {
				var pattern = $@"SMILEY_{i}_INDEX";
				var replacement = $"<img src='{smileys[i].Path}' />";
				processedMessageInput.DisplayBody = Regex.Replace(processedMessageInput.DisplayBody, pattern, replacement);
			}
		}
		/// <summary>
		/// Minor post processing
		/// </summary>
		public void PostProcessMessageInput(InputModels.ProcessedMessageInput processedMessageInput) {
			// make absolutely sure it targets a new window.
			processedMessageInput.DisplayBody = new Regex(@"<a ").Replace(processedMessageInput.DisplayBody, "<a target='_blank' ");

			// trim extra lines from quotes
			processedMessageInput.DisplayBody = new Regex(@"<blockquote(.*?)>(\r|\n|\r\n)*").Replace(processedMessageInput.DisplayBody, match => $"<blockquote{match.Groups[1].Value}>");
			processedMessageInput.DisplayBody = new Regex(@"(\r|\n|\r\n)*</blockquote>(\r|\n|\r\n)*").Replace(processedMessageInput.DisplayBody, "</blockquote>");

			processedMessageInput.DisplayBody = processedMessageInput.DisplayBody.Trim();
			processedMessageInput.ShortPreview = GetMessagePreview(processedMessageInput.DisplayBody, 100);
			processedMessageInput.LongPreview = GetMessagePreview(processedMessageInput.DisplayBody, 500, true);
		}
        public async Task UpdateMessageRecord(InputModels.ProcessedMessageInput message, DataModels.Message record)
        {
            record.OriginalBody = message.OriginalBody;
            record.DisplayBody  = message.DisplayBody;
            record.ShortPreview = message.ShortPreview;
            record.LongPreview  = message.LongPreview;
            record.Cards        = message.Cards;
            record.TimeEdited   = DateTime.Now;

            DbContext.Update(record);

            await DbContext.SaveChangesAsync();
        }
Beispiel #11
0
        public void UpdateMessageRecord(InputModels.ProcessedMessageInput message, DataModels.Message record)
        {
            record.OriginalBody = message.OriginalBody;
            record.DisplayBody  = message.DisplayBody;
            record.ShortPreview = message.ShortPreview;
            record.LongPreview  = message.LongPreview;
            record.Cards        = message.Cards;
            record.TimeEdited   = DateTime.Now;
            record.EditedById   = UserContext.ApplicationUser.Id;
            record.Processed    = true;

            DbContext.Update(record);

            DbContext.SaveChanges();
        }
        /// <summary>
        /// Attempt to replace URLs in the message body with something better
        /// </summary>
        public async Task ProcessMessageBodyUrls(InputModels.ProcessedMessageInput processedMessageInput)
        {
            var displayBody = processedMessageInput.DisplayBody;

            var regexUrl = new Regex("(^| )((https?\\://){1}\\S+)", RegexOptions.Compiled | RegexOptions.Multiline);

            var matches      = 0;
            var replacements = new Dictionary <string, string>();

            foreach (Match regexMatch in regexUrl.Matches(displayBody))
            {
                matches++;

                // DoS prevention
                if (matches > 10)
                {
                    break;
                }

                var siteUrl = regexMatch.Groups[2].Value;

                if (string.IsNullOrEmpty(siteUrl))
                {
                    continue;
                }

                var key = $"SITEURL_{matches}";
                displayBody = displayBody.Replace(siteUrl, key);

                var remoteUrlReplacement = await GetRemoteUrlReplacement(siteUrl);

                if (remoteUrlReplacement != null)
                {
                    replacements.Add(key, remoteUrlReplacement.ReplacementText);
                    processedMessageInput.Cards += remoteUrlReplacement.Card;
                }
            }

            foreach (var kvp in replacements)
            {
                displayBody = displayBody.Replace(kvp.Key, kvp.Value);
            }

            processedMessageInput.DisplayBody = displayBody;
        }
        /// <summary>
        /// Searches a post for references to other users
        /// </summary>
        public async Task FindMentionedUsers(InputModels.ProcessedMessageInput processedMessageInput)
        {
            var regexUsers = new Regex(@"@(\S+)");

            var matches = 0;

            foreach (Match regexMatch in regexUsers.Matches(processedMessageInput.DisplayBody))
            {
                matches++;

                // DoS prevention
                if (matches > 10)
                {
                    break;
                }

                var matchedTag = regexMatch.Groups[1].Value;

                var users = await AccountRepository.Records();

                var user = users.FirstOrDefault(u => u.DisplayName.ToLower() == matchedTag.ToLower());

                // try to guess what they meant
                if (user is null)
                {
                    user = users.FirstOrDefault(u => u.UserName.ToLower().Contains(matchedTag.ToLower()));
                }

                if (user != null)
                {
                    if (user.Id != CurrentUser.Id)
                    {
                        processedMessageInput.MentionedUsers.Add(user.Id);
                    }

                    // UNTESTED
                    //processedMessageInput.DisplayBody = processedMessageInput.DisplayBody.Replace($"{regexMatch.Groups[1].Value}", $"<a href='/Messages/History/{user.Id}'>{user.DisplayName}</span>");
                }
            }
        }
Beispiel #14
0
        /// <summary>
        /// Some minor housekeeping on the message before we get into the heavy lifting.
        /// </summary>
        public InputModels.ProcessedMessageInput PreProcessMessageInput(string messageBody)
        {
            var processedMessageInput = new InputModels.ProcessedMessageInput {
                OriginalBody   = messageBody ?? string.Empty,
                DisplayBody    = messageBody ?? string.Empty,
                MentionedUsers = new List <string>()
            };

            var displayBody = processedMessageInput.DisplayBody.Trim();

            if (string.IsNullOrEmpty(displayBody))
            {
                throw new ArgumentException("Message body is empty.");
            }

            // keep this as close to the smiley replacement as possible to prevent HTML-izing the bracket.
            displayBody = displayBody.Replace("*heartsmiley*", "<3");

            processedMessageInput.DisplayBody = displayBody;

            return(processedMessageInput);
        }
        public async Task <DataModels.Message> CreateMessageRecord(InputModels.ProcessedMessageInput processedMessage)
        {
            var now = DateTime.Now;

            var record = new DataModels.Message {
                OriginalBody = processedMessage.OriginalBody,
                DisplayBody  = processedMessage.DisplayBody,
                ShortPreview = processedMessage.ShortPreview,
                LongPreview  = processedMessage.LongPreview,
                Cards        = processedMessage.Cards,
                TimePosted   = now,
                TimeEdited   = now,
                PostedById   = CurrentUser.Id,
            };

            DbContext.Messages.Add(record);
            await DbContext.SaveChangesAsync();

            await NotifyMentionedUsers(processedMessage.MentionedUsers, record.Id);

            return(record);
        }
        /// <summary>
        /// Some minor housekeeping on the message before we get into the heavy lifting.
        /// </summary>
        public async Task <InputModels.ProcessedMessageInput> PreProcess(InputModels.ProcessedMessageInput processedMessage)
        {
            processedMessage.DisplayBody = processedMessage.DisplayBody.Trim();

            if (string.IsNullOrEmpty(processedMessage.DisplayBody))
            {
                throw new ArgumentException("Message body is empty.");
            }

            var smileys = await SmileyRepository.Records();

            // Ensures the smileys are safe from other HTML processing.
            for (var i = 0; i < smileys.Count(); i++)
            {
                var pattern     = $@"(^|[\r\n\s]){Regex.Escape(smileys[i].Code)}(?=$|[\r\n\s])";
                var replacement = $"$1SMILEY_{i}_INDEX";
                processedMessage.DisplayBody = Regex.Replace(processedMessage.DisplayBody, pattern, replacement, RegexOptions.Singleline);
            }

            processedMessage.DisplayBody = BBCParser.ToHtml(processedMessage.DisplayBody);

            return(processedMessage);
        }
Beispiel #17
0
		/// <summary>
		/// Some minor housekeeping on the message before we get into the heavy lifting.
		/// </summary>
		public async Task<InputModels.ProcessedMessageInput> PreProcessMessageInput(string messageBody) {
			var processedMessageInput = new InputModels.ProcessedMessageInput {
				OriginalBody = messageBody ?? string.Empty,
				DisplayBody = messageBody ?? string.Empty,
				MentionedUsers = new List<string>()
			};

			processedMessageInput.DisplayBody = processedMessageInput.DisplayBody.Trim();

			if (string.IsNullOrEmpty(processedMessageInput.DisplayBody)) {
				throw new ArgumentException("Message body is empty.");
			}

			var smileys = await SmileyRepository.Records();

			// Ensures the smileys are safe from other HTML processing.
			for (var i = 0; i < smileys.Count(); i++) {
				var pattern = $@"(^|[\r\n\s]){Regex.Escape(smileys[i].Code)}(?=$|[\r\n\s])";
				var replacement = $"$1SMILEY_{i}_INDEX";
				processedMessageInput.DisplayBody = Regex.Replace(processedMessageInput.DisplayBody, pattern, replacement, RegexOptions.Singleline);
			}

			return processedMessageInput;
		}
Beispiel #18
0
        public DataModels.Message CreateMessageRecord(InputModels.ProcessedMessageInput processedMessage, DataModels.Message replyRecord)
        {
            var parentId = 0;
            var replyId  = 0;

            DataModels.Message parentMessage = null;

            if (replyRecord != null)
            {
                if (replyRecord.ParentId == 0)
                {
                    parentId = replyRecord.Id;
                    replyId  = 0;

                    parentMessage = replyRecord;
                }
                else
                {
                    parentId = replyRecord.ParentId;
                    replyId  = replyRecord.Id;

                    parentMessage = DbContext.Messages.First(item => item.Id == replyRecord.ParentId);
                }
            }

            var currentTime = DateTime.Now;

            var record = new DataModels.Message {
                OriginalBody = processedMessage.OriginalBody,
                DisplayBody  = processedMessage.DisplayBody,
                ShortPreview = processedMessage.ShortPreview,
                LongPreview  = processedMessage.LongPreview,
                Cards        = processedMessage.Cards,

                TimePosted      = currentTime,
                TimeEdited      = currentTime,
                LastReplyPosted = currentTime,

                PostedById    = UserContext.ApplicationUser.Id,
                EditedById    = UserContext.ApplicationUser.Id,
                LastReplyById = UserContext.ApplicationUser.Id,

                ParentId = parentId,
                ReplyId  = replyId,

                Processed = true
            };

            DbContext.Messages.Add(record);
            DbContext.SaveChanges();

            if (replyId > 0)
            {
                replyRecord.LastReplyId     = record.Id;
                replyRecord.LastReplyById   = UserContext.ApplicationUser.Id;
                replyRecord.LastReplyPosted = currentTime;

                DbContext.Update(replyRecord);

                if (replyRecord.PostedById != UserContext.ApplicationUser.Id)
                {
                    var notification = new DataModels.Notification {
                        MessageId    = record.Id,
                        UserId       = replyRecord.PostedById,
                        TargetUserId = UserContext.ApplicationUser.Id,
                        Time         = DateTime.Now,
                        Type         = Enums.ENotificationType.Quote,
                        Unread       = true,
                    };

                    DbContext.Notifications.Add(notification);
                }
            }

            if (parentMessage != null && parentId != replyId)
            {
                parentMessage.ReplyCount++;
                parentMessage.LastReplyId     = record.Id;
                parentMessage.LastReplyById   = UserContext.ApplicationUser.Id;
                parentMessage.LastReplyPosted = currentTime;

                DbContext.Update(parentMessage);

                if (parentMessage.PostedById != UserContext.ApplicationUser.Id)
                {
                    var notification = new DataModels.Notification {
                        MessageId    = record.Id,
                        UserId       = parentMessage.PostedById,
                        TargetUserId = UserContext.ApplicationUser.Id,
                        Time         = DateTime.Now,
                        Type         = Enums.ENotificationType.Reply,
                        Unread       = true,
                    };

                    DbContext.Notifications.Add(notification);
                }
            }

            NotifyMentionedUsers(processedMessage.MentionedUsers, record.Id);

            var topicId = parentId == 0 ? record.Id : parentId;

            UpdateTopicParticipation(topicId, UserContext.ApplicationUser.Id, DateTime.Now);

            DbContext.SaveChanges();

            return(record);
        }
Beispiel #19
0
		public void ParseBBC(InputModels.ProcessedMessageInput processedMessageInput) {
			processedMessageInput.DisplayBody = BBCParser.ToHtml(processedMessageInput.DisplayBody);
		}