[smuxi: 37/111] Engine(-Tests): implemented SmartLinks with some basic patterns (closes: #498, #911, #923)
- From: Mirco M. M. Bauer <mmmbauer src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [smuxi: 37/111] Engine(-Tests): implemented SmartLinks with some basic patterns (closes: #498, #911, #923)
- Date: Sun, 16 Feb 2014 13:16:32 +0000 (UTC)
commit 1c0f3e543c812005e7d75a62f3199fc5b551be0e
Author: Oliver Schneider <mail oli-obk de>
Date: Wed Jul 17 16:34:26 2013 +0200
Engine(-Tests): implemented SmartLinks with some basic patterns (closes: #498, #911, #923)
src/Engine-Tests/MessageBuilderTests.cs | 181 +++++++++++++++++++++++++++
src/Engine-Tests/MessageModelTests.cs | 2 -
src/Engine-Tests/MessageParserTests.cs | 15 +--
src/Engine/Config/MessageBuilderSettings.cs | 121 ++++++++++++++++++
src/Engine/Engine.csproj | 2 +-
src/Engine/Messages/MessageBuilder.cs | 105 +++++++++++++++-
src/Engine/Messages/MessageParser.cs | 161 ------------------------
src/Engine/Messages/UrlMessagePartModel.cs | 24 ++++
8 files changed, 435 insertions(+), 176 deletions(-)
---
diff --git a/src/Engine-Tests/MessageBuilderTests.cs b/src/Engine-Tests/MessageBuilderTests.cs
index 4355270..448d2fd 100644
--- a/src/Engine-Tests/MessageBuilderTests.cs
+++ b/src/Engine-Tests/MessageBuilderTests.cs
@@ -309,5 +309,186 @@ namespace Smuxi.Engine
var builder = new MessageBuilder();
builder.AppendFormat("{{{{virtual {0}}}}}", "hugs");
}
+
+ void TestMessage(string message, MessageModel expectedMsg)
+ {
+ var builder = new MessageBuilder();
+ builder.TimeStamp = DateTime.MinValue;
+ builder.AppendMessage(message);
+ var actualMsg = builder.ToMessage();
+ Assert.AreEqual(expectedMsg, actualMsg);
+ }
+
+ [Test]
+ public void AppendTextUrlParsingSanity()
+ {
+ var msg = @"http://ab.cd.ef.de-hlub.gummi.museum/my_script%20windows.php?test=blub&blar=93";
+ var builder = new MessageBuilder();
+ builder.TimeStamp = DateTime.MinValue;
+ builder.Append(new UrlMessagePartModel(msg));
+ TestMessage(msg, builder.ToMessage());
+ /*
+ var msg = @"<http://smuxi.im/#sometag>";
+ var msg = @"hey look at this: http://test.org, it is really cool";
+ var msg = @"have you recently looked at xkcd.org?";
+ var msg = @"my homepage (http://mine.my) has nothing on it";
+ var msg = @"[smuxi] meebey pushed 2 new commits to stable:
https://github.com/meebey/smuxi/compare/153153feddd4...ff7d23a7550c";
+ var msg = @"[372 (Motd)] - FOSSCON [http://www.fosscon.org] and fossevents ";
+ var msg = @"[372 (Motd)] - page (http://freenode.net/policy.shtml). Thank you for usin";
+ var msg = @"look at all those deprecated fields pidgin still sets: <c
xmlns=""http://jabber.org/protocol/caps"" hash=""sha-1"" node=""http://pidgin.im/"" ext=""voice-v1 camera-v1
video-v1"" ver=""AcN1/PEN8nq7AHD+9jpxMV4U6YM="" />";
+ var msg = @"16:04:11 <clonkspot> Glückwunsch! (@YouTube http://t.co/IXjWtfGJ5d)";
+ var msg = @"This is a http://sentence.that/ends.with?a. This is another sentence.";
+ */
+ }
+
+ [Test]
+ public void AppendTextUrlParsingLtGtBrackets()
+ {
+ var msg = @"<http://smuxi.im/#sometag>";
+ var url = @"http://smuxi.im/#sometag";
+ var builder = new MessageBuilder();
+ builder.TimeStamp = DateTime.MinValue;
+ builder.Append(new TextMessagePartModel("<"));
+ builder.Append(new UrlMessagePartModel(url));
+ builder.Append(new TextMessagePartModel(">"));
+ TestMessage(msg, builder.ToMessage());
+ }
+ [Test]
+ public void AppendTextUrlParsingUrlEndsInComma()
+ {
+ var msg = @"hey look at this: http://test.org, it is really cool";
+ var url = @"http://test.org";
+ var builder = new MessageBuilder();
+ builder.TimeStamp = DateTime.MinValue;
+ builder.Append(new TextMessagePartModel("hey look at this: "));
+ builder.Append(new UrlMessagePartModel(url));
+ builder.Append(new TextMessagePartModel(", it is really cool"));
+ TestMessage(msg, builder.ToMessage());
+ }
+
+ [Test]
+ public void AppendTextUrlParsingUrlNoProtocol()
+ {
+ var msg = @"hey look at this: test.org";
+ var url = @"http://test.org";
+ var urltext = @"test.org";
+ var builder = new MessageBuilder();
+ builder.TimeStamp = DateTime.MinValue;
+ builder.Append(new TextMessagePartModel("hey look at this: "));
+ builder.Append(new UrlMessagePartModel(url, urltext));
+ TestMessage(msg, builder.ToMessage());
+ }
+
+ [Test]
+ public void AppendTextUrlParsingEndsInQuestionmark()
+ {
+ var msg = @"have you recently looked at xkcd.com?";
+ var url = @"http://xkcd.com";
+ var urltext = @"xkcd.com";
+ var builder = new MessageBuilder();
+ builder.TimeStamp = DateTime.MinValue;
+ builder.Append(new TextMessagePartModel("have you recently looked at "));
+ builder.Append(new UrlMessagePartModel(url, urltext));
+ builder.Append(new TextMessagePartModel("?"));
+ TestMessage(msg, builder.ToMessage());
+ /*
+ var msg = @"my homepage (http://mine.my) has nothing on it";
+ var msg = @"[smuxi] meebey pushed 2 new commits to stable:
https://github.com/meebey/smuxi/compare/153153feddd4...ff7d23a7550c";
+ var msg = @"[372 (Motd)] - FOSSCON [http://www.fosscon.org] and fossevents ";
+ var msg = @"[372 (Motd)] - page (http://freenode.net/policy.shtml). Thank you for usin";
+ var msg = @"look at all those deprecated fields pidgin still sets: <c
xmlns=""http://jabber.org/protocol/caps"" hash=""sha-1"" node=""http://pidgin.im/"" ext=""voice-v1 camera-v1
video-v1"" ver=""AcN1/PEN8nq7AHD+9jpxMV4U6YM="" />";
+ var msg = @"16:04:11 <clonkspot> Glückwunsch! (@YouTube http://t.co/IXjWtfGJ5d)";
+ var msg = @"This is a http://sentence.that/ends.with?a. This is another sentence.";
+ */
+ }
+
+ [Test]
+ public void AppendTextUrlParsingUrlInBrackets()
+ {
+ var msg = @"my homepage (http://mine.my) has nothing on it";
+ var url = @"http://mine.my";
+ var builder = new MessageBuilder();
+ builder.TimeStamp = DateTime.MinValue;
+ builder.Append(new TextMessagePartModel("my homepage ("));
+ builder.Append(new UrlMessagePartModel(url));
+ builder.Append(new TextMessagePartModel(") has nothing on it"));
+ TestMessage(msg, builder.ToMessage());
+ }
+
+ [Test]
+ public void AppendTextUrlGithubMessage()
+ {
+ var msg = @"[smuxi] meebey pushed 2 new commits to stable:
https://github.com/meebey/smuxi/compare/153153feddd4...ff7d23a7550c";
+ var url = @"https://github.com/meebey/smuxi/compare/153153feddd4...ff7d23a7550c";
+ var builder = new MessageBuilder();
+ builder.TimeStamp = DateTime.MinValue;
+ builder.Append(new TextMessagePartModel("[smuxi] meebey pushed 2 new commits to stable: "));
+ builder.Append(new UrlMessagePartModel(url));
+ TestMessage(msg, builder.ToMessage());
+ }
+
+ [Test]
+ public void AppendTextUrlSquareBrackets()
+ {
+ var msg = @"[372 (Motd)] - FOSSCON [http://www.fosscon.org] and fossevents ";
+ var url = @"http://www.fosscon.org";
+ var builder = new MessageBuilder();
+ builder.TimeStamp = DateTime.MinValue;
+ builder.Append(new TextMessagePartModel("[372 (Motd)] - FOSSCON ["));
+ builder.Append(new UrlMessagePartModel(url));
+ builder.Append(new TextMessagePartModel("] and fossevents "));
+ TestMessage(msg, builder.ToMessage());
+ }
+
+ [Test]
+ public void AppendTextUrlNormalBrackets()
+ {
+ var msg = @"[372 (Motd)] - page (http://freenode.net/policy.shtml). Thank you for usin";
+ var url = @"http://freenode.net/policy.shtml";
+ var builder = new MessageBuilder();
+ builder.TimeStamp = DateTime.MinValue;
+ builder.Append(new TextMessagePartModel("[372 (Motd)] - page ("));
+ builder.Append(new UrlMessagePartModel(url));
+ builder.Append(new TextMessagePartModel("). Thank you for usin"));
+ TestMessage(msg, builder.ToMessage());
+ }
+
+ [Test]
+ public void AppendTextUrlMultipleInQuotes()
+ {
+ var msg = @"look at all those deprecated fields pidgin still sets: <c
xmlns=""http://jabber.org/protocol/caps"" hash=""sha-1"" node=""http://pidgin.im/"" ext=""voice-v1 camera-v1
video-v1"" ver=""AcN1/PEN8nq7AHD+9jpxMV4U6YM="" />";
+ var builder = new MessageBuilder();
+ builder.TimeStamp = DateTime.MinValue;
+ builder.Append(new TextMessagePartModel(@"look at all those deprecated fields pidgin still sets:
<c xmlns="""));
+ builder.Append(new UrlMessagePartModel("http://jabber.org/protocol/caps"));
+ builder.Append(new TextMessagePartModel(@""" hash=""sha-1"" node="""));
+ builder.Append(new UrlMessagePartModel("http://pidgin.im/"));
+ builder.Append(new TextMessagePartModel(@""" ext=""voice-v1 camera-v1 video-v1""
ver=""AcN1/PEN8nq7AHD+9jpxMV4U6YM="" />"));
+ TestMessage(msg, builder.ToMessage());
+ }
+
+ [Test]
+ public void AppendTextUrlEndsInClosedBracket()
+ {
+ var msg = @"16:04:11 <clonkspot> Glückwunsch! (@YouTube http://t.co/IXjWtfGJ5d)";
+ var builder = new MessageBuilder();
+ builder.TimeStamp = DateTime.MinValue;
+ builder.Append(new TextMessagePartModel(@"16:04:11 <clonkspot> Glückwunsch! (@YouTube "));
+ builder.Append(new UrlMessagePartModel("http://t.co/IXjWtfGJ5d"));
+ builder.Append(new TextMessagePartModel(@")"));
+ TestMessage(msg, builder.ToMessage());
+ }
+
+ [Test]
+ public void AppendTextUrlEndsInDot()
+ {
+ var msg = @"This is a http://sentence.th/at/ends.with?a. This is another sentence.";
+ var builder = new MessageBuilder();
+ builder.TimeStamp = DateTime.MinValue;
+ builder.Append(new TextMessagePartModel(@"This is a "));
+ builder.Append(new UrlMessagePartModel("http://sentence.th/at/ends.with?a"));
+ builder.Append(new TextMessagePartModel(@". This is another sentence."));
+ TestMessage(msg, builder.ToMessage());
+ }
}
}
diff --git a/src/Engine-Tests/MessageModelTests.cs b/src/Engine-Tests/MessageModelTests.cs
index ce6c1e7..031879b 100644
--- a/src/Engine-Tests/MessageModelTests.cs
+++ b/src/Engine-Tests/MessageModelTests.cs
@@ -137,7 +137,6 @@ namespace Smuxi.Engine
var msg = new MessageModel(topic) {
IsCompactable = false
};
- MessageParser.ParseUrls(msg);
var stream = new MemoryStream(1024);
formatter.Serialize(stream, msg);
@@ -199,7 +198,6 @@ namespace Smuxi.Engine
)
);
msg.MessageParts.Add(new TextMessagePartModel(" kannst ja watchen"));
- MessageParser.ParseUrls(msg);
stream = new MemoryStream(1024);
formatter.Serialize(stream, msg);
diff --git a/src/Engine-Tests/MessageParserTests.cs b/src/Engine-Tests/MessageParserTests.cs
index bf69907..100833e 100644
--- a/src/Engine-Tests/MessageParserTests.cs
+++ b/src/Engine-Tests/MessageParserTests.cs
@@ -36,9 +36,8 @@ namespace Smuxi.Engine
builder = new MessageBuilder();
builder.TimeStamp = DateTime.MinValue;
- builder.AppendText("http://example.com");
+ builder.AppendRichText("http://example.com");
var actualMsg = builder.ToMessage();
- MessageParser.ParseUrls(actualMsg);
Assert.AreEqual(expectedMsg, actualMsg);
}
@@ -48,16 +47,15 @@ namespace Smuxi.Engine
{
var builder = new MessageBuilder();
builder.TimeStamp = DateTime.MinValue;
- builder.AppendText("foo ");
- builder.AppendUrl("http://example.com", "<http://example.com>");
- builder.AppendText(" bar");
+ builder.AppendText("foo <");
+ builder.AppendUrl("http://example.com");
+ builder.AppendText("> bar");
var expectedMsg = builder.ToMessage();
builder = new MessageBuilder();
builder.TimeStamp = DateTime.MinValue;
- builder.AppendText("foo <http://example.com> bar");
+ builder.AppendRichText("foo <http://example.com> bar");
var actualMsg = builder.ToMessage();
- MessageParser.ParseUrls(actualMsg);
Assert.AreEqual(expectedMsg, actualMsg);
}
@@ -74,9 +72,8 @@ namespace Smuxi.Engine
builder = new MessageBuilder();
builder.TimeStamp = DateTime.MinValue;
- builder.AppendText("foo (http://example.com) bar");
+ builder.AppendRichText("foo (http://example.com) bar");
var actualMsg = builder.ToMessage();
- MessageParser.ParseUrls(actualMsg);
Assert.AreEqual(expectedMsg, actualMsg);
}
diff --git a/src/Engine/Config/MessageBuilderSettings.cs b/src/Engine/Config/MessageBuilderSettings.cs
new file mode 100644
index 0000000..12d5495
--- /dev/null
+++ b/src/Engine/Config/MessageBuilderSettings.cs
@@ -0,0 +1,121 @@
+// Smuxi - Smart MUltipleXed Irc
+//
+// Copyright (c) 2011 Mirco Bauer <meebey meebey net>
+//
+// Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+using System;
+using System.Text.RegularExpressions;
+using System.Collections.Generic;
+
+namespace Smuxi.Engine
+{
+ public class MessageBuilderSettings
+ {
+
+ public class SmartLink
+ {
+ public enum ETargetType
+ {
+ Text, Url, Image
+ }
+
+ public Regex MessagePartPattern { get; set; }
+ // what is linked to
+ public string LinkFormat { get; set; }
+ // what is displayed
+ public string TextFormat { get; set; }
+ public ETargetType Type { get; set; }
+ };
+
+ public List<SmartLink> SmartLinks { get; private set; }
+
+ void CreateSmartLink(Regex regex)
+ {
+ CreateSmartLink(regex, null, null);
+ }
+
+ void CreateSmartLink(Regex regex, string linkPattern)
+ {
+ CreateSmartLink(regex, linkPattern, null);
+ }
+
+ void CreateSmartLink(Regex regex, string linkPattern, string textPattern)
+ {
+ var link = new SmartLink();
+ link.MessagePartPattern = regex;
+ link.LinkFormat = linkPattern;
+ link.TextFormat = textPattern;
+ link.Type = SmartLink.ETargetType.Url;
+ SmartLinks.Add(link);
+ }
+
+ void CreateSmartText(Regex regex, string textPattern)
+ {
+ var link = new SmartLink();
+ link.MessagePartPattern = regex;
+ link.TextFormat = textPattern;
+ link.Type = SmartLink.ETargetType.Text;
+ SmartLinks.Add(link);
+ }
+
+ public MessageBuilderSettings()
+ {
+ SmartLinks = new List<SmartLink>();
+ string path_last_chars = @"a-z0-9#/%&=\-_+";
+ string path_chars = path_last_chars + @")(?.,";
+ string domainchars = @"[a-z0-9\-]+";
+ string subdomain = domainchars + @"\.";
+ string tld = @"com|net|org|info|biz|gov|name|edu|museum|[a-z][a-z]";
+ string domain = @"(?:(?:" + subdomain + ")+(?:" + tld + ")|localhost)";
+ string port = ":[1-9][0-9]{1,4}";
+ string domain_port = domain + "(?:" + port + ")?";
+ string path = @"/(?:["+ path_chars +"]*["+ path_last_chars +"]+)?";
+ string address = domain_port + "(?:" + path + ")?";
+
+ // facebook attachment
+ CreateSmartLink(new Regex(@"(<[1-9][0-9]* attachments?>)
(http://www\.facebook\.com/messages/\?action=read&tid=[0-9a-f]+)"), "{2}", "{1}");
+
+ // protocol://domain
+ CreateSmartLink(new Regex(@"[a-z][a-z0-9\-]*://" + address, RegexOptions.IgnoreCase));
+
+ // E-Mail
+ CreateSmartLink(new Regex(@"([a-z0-9._%+-]+@(?:[a-z0-9-]+\.)+[a-z]{2,})",
RegexOptions.IgnoreCase), "mailto:{0}");
+ // addresses without protocol
+ CreateSmartLink(new Regex(address, RegexOptions.IgnoreCase), "http://{0}");
+ // smuxi bugtracker
+ CreateSmartLink(new Regex(@"#([0-9]+)"), "http://www.smuxi.org/issues/{0}");
+
+ // TODO: msgid -> http://mid.gmane.org/{1}
+ // TODO: RFC -> http://www.ietf.org/rfc/rfc{1}.txt
+ // TODO: CVE-YYYY-XXXX -> http://cve.mitre.org/cgi-bin/cvename.cgi?name={1}
+ // TODO: ISSN/ISBN
+ // TODO: Path: / or X:\
+ // TODO: GPS -> Google Maps
+ // TODO: IP -> Browser / Whois
+ // TODO: Domain -> Browser / Whois
+ // TODO: ISO -> http://www.iso.org/iso/search.htm?qt={1}&published=on
+ // TODO: ANSI
+ // TODO: ECMA
+ // TODO: maybe more on http://ikiwiki.info/shortcuts/
+ // TODO: JID
+ }
+
+ public void ApplyConfig(UserConfig userConfig)
+ {
+ }
+ }
+}
diff --git a/src/Engine/Engine.csproj b/src/Engine/Engine.csproj
index b593a18..b2a4a07 100644
--- a/src/Engine/Engine.csproj
+++ b/src/Engine/Engine.csproj
@@ -80,7 +80,6 @@
<Compile Include="Config\UserListController.cs" />
<Compile Include="Config\FilterListController.cs" />
<Compile Include="Config\FilterModel.cs" />
- <Compile Include="Messages\MessageParser.cs" />
<Compile Include="Messages\MessageBuilder.cs" />
<Compile Include="PresenceStatus.cs" />
<Compile Include="Config\ProxyType.cs" />
@@ -106,6 +105,7 @@
<Compile Include="Hooks\Commands\ProtocolManagerHookCommand.cs" />
<Compile Include="Hooks\Commands\SessionHookCommand.cs" />
<Compile Include="Hooks\Environments\CommandHookEnvironment.cs" />
+ <Compile Include="Config\MessageBuilderSettings.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="Protocols\" />
diff --git a/src/Engine/Messages/MessageBuilder.cs b/src/Engine/Messages/MessageBuilder.cs
index cc15d60..87041e6 100644
--- a/src/Engine/Messages/MessageBuilder.cs
+++ b/src/Engine/Messages/MessageBuilder.cs
@@ -20,6 +20,7 @@
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
using System;
+using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections.Generic;
@@ -43,6 +44,7 @@ namespace Smuxi.Engine
public TextColor HighlightColor { get; set; }
public List<string> HighlightWords { get; set; }
public PersonModel Me { get; set; }
+ public MessageBuilderSettings Settings { get; private set; }
public MessageType MessageType {
get {
@@ -71,13 +73,12 @@ namespace Smuxi.Engine
public MessageBuilder()
{
Message = new MessageModel();
+ Settings = new MessageBuilderSettings();
NickColors = true;
}
public MessageModel ToMessage()
{
- //MessageParser.ParseSmileys
- MessageParser.ParseUrls(Message);
Message.Compact();
return Message;
}
@@ -272,9 +273,15 @@ namespace Smuxi.Engine
return AppendText(CreateHeader(text, args));
}
+ [Obsolete("AppendMessage() is deprecated, use AppendRichText() instead")]
public virtual MessageBuilder AppendMessage(string msg)
{
- return AppendText(msg);
+ return AppendRichText(msg);
+ }
+
+ public virtual MessageBuilder AppendRichText(string msg)
+ {
+ return Append(ParseSmartLinks(CreateText(msg)));
}
public MessageBuilder AppendMessage(ContactModel sender, string msg)
@@ -854,5 +861,97 @@ namespace Smuxi.Engine
{
return LibraryCatalog.GetString(msg, LibraryTextDomain);
}
+
+ public static IList<MessagePartModel> ParseSmartLinks(TextMessagePartModel textPart,
+ List<MessageBuilderSettings.SmartLink> links)
+ {
+ IList<MessagePartModel> msg = new List<MessagePartModel>();
+ if (links.Count == 0) {
+ // all smartlinks have been tried -> this text is PURE text
+ msg.Add(textPart);
+ return msg;
+ }
+ var subLinks = new List<MessageBuilderSettings.SmartLink>(links);
+ MessageBuilderSettings.SmartLink link = subLinks.First();
+ subLinks.Remove(link);
+
+ Match linkMatch = link.MessagePartPattern.Match(textPart.Text);
+ if (!linkMatch.Success) {
+ // no smartlinks in this MessagePart, try other smartlinks
+ return ParseSmartLinks(textPart, subLinks);
+ }
+
+ int lastindex = 0;
+ do {
+ var groupValues = new string[linkMatch.Groups.Count];
+ int i = 0;
+ foreach (Group @group in linkMatch.Groups) {
+ groupValues[i++] = @group.Value;
+ }
+
+ string url;
+ if (link.LinkFormat != null) {
+ url = String.Format(link.LinkFormat, groupValues);
+ } else {
+ url = linkMatch.Value;
+ }
+ string text;
+ if (link.TextFormat != null) {
+ text = String.Format(link.TextFormat, groupValues);
+ } else {
+ text = (linkMatch.Value == url)?null:linkMatch.Value;
+ }
+
+
+ if (lastindex != linkMatch.Index) {
+ // there were some non-url-chars before this url
+ // copy TextMessagePartModel
+ TextMessagePartModel notLinkPart = new TextMessagePartModel(textPart);
+ // only take the proper chunk of text
+ notLinkPart.Text = textPart.Text.Substring(lastindex, linkMatch.Index-lastindex);
+ // and try other smartlinks on this part
+ var parts = ParseSmartLinks(notLinkPart, subLinks);
+ foreach (var part in parts) {
+ msg.Add(part);
+ }
+ }
+
+ MessagePartModel model;
+ switch (link.Type) {
+ case MessageBuilderSettings.SmartLink.ETargetType.Url:
+ model = new UrlMessagePartModel(url, text);
+ break;
+ case MessageBuilderSettings.SmartLink.ETargetType.Image:
+ model = new ImageMessagePartModel(url, text);
+ break;
+ case MessageBuilderSettings.SmartLink.ETargetType.Text:
+ default:
+ model = new TextMessagePartModel(text);
+ break;
+ }
+ msg.Add(model);
+ lastindex = linkMatch.Index + linkMatch.Length;
+ linkMatch = linkMatch.NextMatch();
+ } while (linkMatch.Success);
+
+ if (lastindex != textPart.Text.Length) {
+ // there were some non-url-chars before this url
+ // copy TextMessagePartModel
+ TextMessagePartModel notLinkPart = new TextMessagePartModel(textPart);
+ // only take the proper chunk of text
+ notLinkPart.Text = textPart.Text.Substring(lastindex);
+ // and try other smartlinks on this part
+ var parts = ParseSmartLinks(notLinkPart, subLinks);
+ foreach (var part in parts) {
+ msg.Add(part);
+ }
+ }
+ return msg;
+ }
+
+ public IEnumerable<MessagePartModel> ParseSmartLinks(TextMessagePartModel part)
+ {
+ return ParseSmartLinks(part, Settings.SmartLinks);
+ }
}
}
diff --git a/src/Engine/Messages/UrlMessagePartModel.cs b/src/Engine/Messages/UrlMessagePartModel.cs
index 8c4c83b..e738e2d 100644
--- a/src/Engine/Messages/UrlMessagePartModel.cs
+++ b/src/Engine/Messages/UrlMessagePartModel.cs
@@ -120,5 +120,29 @@ namespace Smuxi.Engine
return "[" + _Url + " " + Text + "]";
}
}
+
+ public override bool Equals(object obj)
+ {
+ if (!(obj is UrlMessagePartModel)) {
+ return false;
+ }
+
+ var urlPart = (UrlMessagePartModel) obj;
+ return Equals(urlPart);
+ }
+
+ public override bool Equals(MessagePartModel part)
+ {
+ var urlPart = part as UrlMessagePartModel;
+ if ((object) urlPart == null) {
+ return false;
+ }
+
+ if (_Url != urlPart._Url) {
+ return false;
+ }
+
+ return base.Equals(urlPart);
+ }
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]