Merge pull request #83 from RockyTV/caps
Add complete support for server-time cap
This commit is contained in:
commit
5281bd9a47
|
@ -163,8 +163,12 @@ namespace ChatSharp
|
|||
Users = new UserPool();
|
||||
Users.Add(User); // Add self to user pool
|
||||
Capabilities = new CapabilityPool();
|
||||
|
||||
// List of supported capabilities
|
||||
Capabilities.AddRange(new string[] { "server-time", "multi-prefix", "cap-notify" });
|
||||
Capabilities.AddRange(new string[] {
|
||||
"server-time", "multi-prefix", "cap-notify", "znc.in/server-time", "znc.in/server-time-iso"
|
||||
});
|
||||
|
||||
IsNegotiatingCapabilities = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,10 @@ namespace ChatSharp
|
|||
/// The message tags.
|
||||
/// </summary>
|
||||
public KeyValuePair<string, string>[] Tags { get; private set; }
|
||||
/// <summary>
|
||||
/// The message timestamp in ISO 8601 format.
|
||||
/// </summary>
|
||||
public Timestamp Timestamp { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes and decodes an IRC message, given the raw message from the server.
|
||||
|
@ -98,6 +102,22 @@ namespace ChatSharp
|
|||
Command = rawMessage;
|
||||
Parameters = new string[0];
|
||||
}
|
||||
|
||||
// Parse server-time message tag.
|
||||
// Fallback to server-info if both znc.in/server-info and the former exists.
|
||||
//
|
||||
// znc.in/server-time tag
|
||||
if (Tags.Any(tag => tag.Key == "t"))
|
||||
{
|
||||
var tag = Tags.SingleOrDefault(x => x.Key == "t");
|
||||
Timestamp = new Timestamp(tag.Value, true);
|
||||
}
|
||||
// server-time tag
|
||||
else if (Tags.Any(tag => tag.Key == "time"))
|
||||
{
|
||||
var tag = Tags.SingleOrDefault(x => x.Key == "time");
|
||||
Timestamp = new Timestamp(tag.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
|
||||
namespace ChatSharp
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a message timestamp received from a server.
|
||||
/// </summary>
|
||||
public class Timestamp
|
||||
{
|
||||
/// <summary>
|
||||
/// A date representation of the timestamp.
|
||||
/// </summary>
|
||||
public DateTime Date { get; internal set; }
|
||||
/// <summary>
|
||||
/// A unix epoch representation of the timestamp.
|
||||
/// </summary>
|
||||
public double UnixTimestamp { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes and parses the timestamp received from the server.
|
||||
/// </summary>
|
||||
/// <param name="date"></param>
|
||||
/// <param name="compatibility">Enable pre-ZNC 1.0 compatibility. In previous versions of the tag,
|
||||
/// servers sent a unix timestamp instead of a ISO 8601 string.</param>
|
||||
internal Timestamp(string date, bool compatibility = false)
|
||||
{
|
||||
if (!compatibility)
|
||||
{
|
||||
DateTime parsedDate;
|
||||
if (!DateTime.TryParseExact(date, @"yyyy-MM-dd\THH:mm:ss.fff\Z", CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out parsedDate))
|
||||
throw new ArgumentException("The date string was provided in an invalid format.", date);
|
||||
|
||||
Date = parsedDate;
|
||||
UnixTimestamp = Date.Subtract(new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds;
|
||||
}
|
||||
else
|
||||
{
|
||||
double parsedTimestamp;
|
||||
if (!double.TryParse(date, out parsedTimestamp))
|
||||
throw new ArgumentException("The timestamp string was provided in an invalid format.", date);
|
||||
|
||||
UnixTimestamp = parsedTimestamp;
|
||||
Date = (new DateTime(1970, 1, 1, 0, 0, 0).AddSeconds(UnixTimestamp));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// True if this timestamp is equal to another (compares unix timestamps).
|
||||
/// </summary>
|
||||
public bool Equals(Timestamp other)
|
||||
{
|
||||
return other.UnixTimestamp == UnixTimestamp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// True if this timestamp is equal to another (compares unix timestamps).
|
||||
/// </summary>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is Timestamp)
|
||||
return Equals((Timestamp)obj);
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a ISO 8601 string representation of the timestamp.
|
||||
/// </summary>
|
||||
public string ToISOString()
|
||||
{
|
||||
return Date.ToString(@"yyyy-MM-dd\THH:mm:ss.fff\Z");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the hash code of the unix timestamp.
|
||||
/// </summary>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return UnixTimestamp.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -81,5 +81,45 @@ namespace ChatSharp.Tests
|
|||
};
|
||||
CollectionAssert.AreEqual(fromMessage.Tags, compareTags);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Timestamp_CompareISOString()
|
||||
{
|
||||
IrcMessage[] messages = {
|
||||
new IrcMessage("@time=2011-10-19T16:40:51.620Z :Angel!angel@example.org PRIVMSG Wiz :Hello"),
|
||||
new IrcMessage("@time=2012-06-30T23:59:59.419Z :John!~john@1.2.3.4 JOIN #chan")
|
||||
};
|
||||
|
||||
string[] timestamps = {
|
||||
"2011-10-19T16:40:51.620Z",
|
||||
"2012-06-30T23:59:59.419Z"
|
||||
};
|
||||
|
||||
Assert.AreEqual(messages[0].Timestamp.ToISOString(), timestamps[0]);
|
||||
Assert.AreEqual(messages[1].Timestamp.ToISOString(), timestamps[1]);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Timestamp_FromTimestamp()
|
||||
{
|
||||
IrcMessage[] messages = {
|
||||
new IrcMessage("@t=1504923966 :Angel!angel@example.org PRIVMSG Wiz :Hello"),
|
||||
new IrcMessage("@t=1504923972 :John!~john@1.2.3.4 JOIN #chan")
|
||||
};
|
||||
|
||||
string[] timestamps = {
|
||||
"2017-09-09T02:26:06.000Z",
|
||||
"2017-09-09T02:26:12.000Z"
|
||||
};
|
||||
|
||||
Assert.AreEqual(messages[0].Timestamp.ToISOString(), timestamps[0]);
|
||||
Assert.AreEqual(messages[1].Timestamp.ToISOString(), timestamps[1]);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Timestamp_FailOnLeap()
|
||||
{
|
||||
Assert.ThrowsException<ArgumentException>(() => new IrcMessage("@time=2012-06-30T23:59:60.419Z :John!~john@1.2.3.4 JOIN #chan"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue