diff --git a/.gitignore b/.gitignore index 84cd940..90c5fa3 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ local.properties .classpath .settings/ .loadpath +.vs/ # External tool builders .externalToolBuilders/ diff --git a/README.md b/README.md index 2d3ac70..e5e0e7d 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ # SlackAPI -This is a third party implementation of Slack's API written in C#. This supports their WebAPI aswell as their Real Time Messaging API. +This is a third party implementation of Slack's API written in C#. This supports their WebAPI as well as their Real Time Messaging API. # Examples @@ -24,7 +24,7 @@ Want committer access? Feel like I'm too lazy to keep up with Slack's ever chang Create some pull requests, give me a reason to give you access. -# Howto build the solution +# How to build the solution ###### (aka where is the config.json file?) The project **SlackAPI.Tests** requires a valid `config.json` file for tests. You have two options to build the solution: - Unload SlackAPI.Tests project and you're able to build SlackAPI solution. diff --git a/SlackAPI.Console/Program.cs b/SlackAPI.Console/Program.cs index 9df9ec0..015b2f2 100644 --- a/SlackAPI.Console/Program.cs +++ b/SlackAPI.Console/Program.cs @@ -1,10 +1,5 @@ -using SlackAPI; -using System; -using System.Collections.Generic; +using System; using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Web; namespace SlackAPI @@ -31,7 +26,7 @@ static void Main(string[] args) // start... var state = Guid.NewGuid().ToString(); - var uri = SlackClient.GetAuthorizeUri(clientId, SlackScope.Identify | SlackScope.Read | SlackScope.Post, redirectUri, state, "socialsaleslounge"); + var uri = SlackClient.GetAuthorizeUri(clientId, SlackScope.Identify | SlackScope.Read | SlackScope.Post | SlackScope.Client, redirectUri, state, "socialsaleslounge"); Console.WriteLine("Directing to: " + uri); Process.Start(uri.ToString()); diff --git a/SlackAPI.Tests/Configuration/IntegrationCollection.cs b/SlackAPI.Tests/Configuration/IntegrationCollection.cs index 2b8c8e0..1bd0a18 100644 --- a/SlackAPI.Tests/Configuration/IntegrationCollection.cs +++ b/SlackAPI.Tests/Configuration/IntegrationCollection.cs @@ -2,8 +2,8 @@ namespace SlackAPI.Tests.Configuration { - [CollectionDefinition("Integration tests")] - public class IntegrationCollection : ICollectionFixture - { - } + [CollectionDefinition("Integration tests")] + public class IntegrationCollection : ICollectionFixture + { + } } diff --git a/SlackAPI.Tests/Configuration/IntegrationFixture.cs b/SlackAPI.Tests/Configuration/IntegrationFixture.cs index 2ee925d..79638b7 100755 --- a/SlackAPI.Tests/Configuration/IntegrationFixture.cs +++ b/SlackAPI.Tests/Configuration/IntegrationFixture.cs @@ -1,8 +1,8 @@ -using System; +using Newtonsoft.Json; +using SlackAPI.Tests.Helpers; +using System; using System.IO; using System.Reflection; -using Newtonsoft.Json; -using SlackAPI.Tests.Helpers; using Xunit; namespace SlackAPI.Tests.Configuration @@ -13,6 +13,7 @@ public IntegrationFixture() { this.Config = this.GetConfig(); this.UserClient = this.GetClient(this.Config.UserAuthToken); + this.UserClientWithPresence = this.GetClient(this.Config.UserAuthToken, new[] { new Tuple("batch_presence_aware", "true") }); this.BotClient = this.GetClient(this.Config.BotAuthToken); } @@ -20,11 +21,14 @@ public IntegrationFixture() public SlackSocketClient UserClient { get; } + public SlackSocketClient UserClientWithPresence { get; } + public SlackSocketClient BotClient { get; } public void Dispose() { this.UserClient.CloseSocket(); + this.UserClientWithPresence.CloseSocket(); this.BotClient.CloseSocket(); } @@ -35,18 +39,18 @@ private SlackConfig GetConfig() string fileName = Path.Combine(assemblyDirectory, @"configuration\config.json"); string json = System.IO.File.ReadAllText(fileName); - var jsonObject = new {slack = (SlackConfig)null }; + var jsonObject = new { slack = (SlackConfig)null }; return JsonConvert.DeserializeAnonymousType(json, jsonObject).slack; } - private SlackSocketClient GetClient(string authToken) + private SlackSocketClient GetClient(string authToken, Tuple[] loginParameters = null) { SlackSocketClient client; using (var syncClient = new InSync($"{nameof(SlackClient.Connect)} - Connected callback")) using (var syncClientSocket = new InSync($"{nameof(SlackClient.Connect)} - SocketConnected callback")) { - client = new SlackSocketClient(authToken); + client = new SlackSocketClient(authToken, loginParameters); client.Connect(x => { Console.WriteLine("Connected"); diff --git a/SlackAPI.Tests/Configuration/SlackConfig.cs b/SlackAPI.Tests/Configuration/SlackConfig.cs index dbaaa67..84111b6 100644 --- a/SlackAPI.Tests/Configuration/SlackConfig.cs +++ b/SlackAPI.Tests/Configuration/SlackConfig.cs @@ -4,7 +4,7 @@ public class SlackConfig { public string UserAuthToken { get; set; } public string BotAuthToken { get; set; } - public string TestChannel { get; set; } + public string TestChannelId { get; set; } public string DirectMessageUser { get; set; } public string AuthCode { get; set; } public string ClientId { get; set; } diff --git a/SlackAPI.Tests/Configuration/config.default.json b/SlackAPI.Tests/Configuration/config.default.json index bec134d..244df4b 100644 --- a/SlackAPI.Tests/Configuration/config.default.json +++ b/SlackAPI.Tests/Configuration/config.default.json @@ -2,10 +2,10 @@ "slack": { "userAuthToken": "token-tokentoken-tokentoken-tokentoken-token", "botAuthToken": "bottoken-bottoken-bottoken-bottoken", - "testChannel": "SuperSecretChannel", - "directMessageUser": "someUserId", - "authCode": "some-super-secret-code-from-Slack-specially-created-for-you-=)", - "clientId": "your-special-id", - "clientSecret": "such-special-secret-key" + "testChannelId": "someChannelId", + "directMessageUser": "someUserId", + "authCode": "some-super-secret-code-from-Slack-specially-created-for-you-=)", + "clientId": "your-special-id", + "clientSecret": "such-special-secret-key" } } diff --git a/SlackAPI.Tests/Connect.cs b/SlackAPI.Tests/Connect.cs index 175ef0f..0bb4cc7 100644 --- a/SlackAPI.Tests/Connect.cs +++ b/SlackAPI.Tests/Connect.cs @@ -24,6 +24,13 @@ public void TestConnectAsUser() Assert.True(client.IsConnected, "Invalid, doesn't think it's connected."); } + [Fact] + public void TestConnectAsUserWithPresence() + { + var client = this.fixture.UserClientWithPresence; + Assert.True(client.IsConnected, "Invalid, doesn't think it's connected."); + } + [Fact(Skip = "Unable to get a working test with data we have in config.json")] public void TestGetAccessToken() { @@ -34,7 +41,7 @@ public void TestGetAccessToken() // act var accessTokenResponse = GetAccessToken(clientId, clientSecret, "", authCode); - + // assert Assert.NotNull(accessTokenResponse); Assert.NotNull(accessTokenResponse.bot); @@ -71,7 +78,7 @@ public void TestConnectPostAndDelete() { // given SlackSocketClient client = this.fixture.UserClient; - string channel = this.fixture.Config.TestChannel; + string channel = this.fixture.Config.TestChannelId; // when DateTime messageTimestamp = PostMessage(client, channel); diff --git a/SlackAPI.Tests/Helpers/InSync.cs b/SlackAPI.Tests/Helpers/InSync.cs index 184680f..f8355d5 100644 --- a/SlackAPI.Tests/Helpers/InSync.cs +++ b/SlackAPI.Tests/Helpers/InSync.cs @@ -1,6 +1,6 @@ using System; -using System.Threading; using System.Runtime.CompilerServices; +using System.Threading; using Xunit; namespace SlackAPI.Tests.Helpers diff --git a/SlackAPI.Tests/JoinDirectMessageChannel.cs b/SlackAPI.Tests/JoinDirectMessageChannel.cs index 237ede3..1b4c851 100644 --- a/SlackAPI.Tests/JoinDirectMessageChannel.cs +++ b/SlackAPI.Tests/JoinDirectMessageChannel.cs @@ -32,7 +32,7 @@ public void ShouldJoinDirectMessageChannel() client.JoinDirectMessageChannel(response => { actual = response; - sync.Proceed();; + sync.Proceed(); ; }, user); } diff --git a/SlackAPI.Tests/PostMessage.cs b/SlackAPI.Tests/PostMessage.cs index b1949dd..442df89 100644 --- a/SlackAPI.Tests/PostMessage.cs +++ b/SlackAPI.Tests/PostMessage.cs @@ -30,7 +30,7 @@ public void SimpleMessageDelivery() actual = response; sync.Proceed(); }, - this.fixture.Config.TestChannel, + this.fixture.Config.TestChannelId, "Hi there!"); } @@ -56,7 +56,7 @@ public void Attachments() actual = response; sync.Proceed(); }, - this.fixture.Config.TestChannel, + this.fixture.Config.TestChannelId, string.Empty, attachments: SlackMother.SomeAttachments); } @@ -81,7 +81,7 @@ public void AttachmentsWithActions() actual = response; sync.Proceed(); }, - this.fixture.Config.TestChannel, + this.fixture.Config.TestChannelId, string.Empty, attachments: SlackMother.SomeAttachmentsWithActions); } diff --git a/SlackAPI.Tests/PresenceSub.cs b/SlackAPI.Tests/PresenceSub.cs new file mode 100644 index 0000000..a11ac50 --- /dev/null +++ b/SlackAPI.Tests/PresenceSub.cs @@ -0,0 +1,41 @@ +using SlackAPI.Tests.Configuration; +using SlackAPI.Tests.Helpers; +using System.Linq; +using Xunit; + +namespace SlackAPI.Tests +{ + [Collection("Integration tests")] + public class PresenceSub + { + private readonly IntegrationFixture fixture; + + public PresenceSub(IntegrationFixture fixture) + { + this.fixture = fixture; + } + + [Fact] + public void PresenceSubscribe() + { + var client = this.fixture.UserClientWithPresence; + var directMessageUser = client.Users.FirstOrDefault(x => x.name == this.fixture.Config.DirectMessageUser); + Assert.NotNull(directMessageUser); + + //UserListResponse actual = null; + using (var sync = new InSync(nameof(SlackClient.UserLookup))) + { + client.OnPresenceChangeReceived += (user) => + { + + }; + client.OnUserChangeReceived += (user) => + { + + }; + client.SendPresenceSub(new[] { directMessageUser.id }); + sync.Proceed(); + } + } + } +} \ No newline at end of file diff --git a/SlackAPI.Tests/SlackAPI.Tests.csproj b/SlackAPI.Tests/SlackAPI.Tests.csproj index 1389905..b738631 100644 --- a/SlackAPI.Tests/SlackAPI.Tests.csproj +++ b/SlackAPI.Tests/SlackAPI.Tests.csproj @@ -73,6 +73,7 @@ + diff --git a/SlackAPI.Tests/Update.cs b/SlackAPI.Tests/Update.cs index d02d1a5..c60bcbd 100644 --- a/SlackAPI.Tests/Update.cs +++ b/SlackAPI.Tests/Update.cs @@ -1,11 +1,12 @@ using SlackAPI.Tests.Configuration; using SlackAPI.Tests.Helpers; +using System; using Xunit; namespace SlackAPI.Tests { [Collection("Integration tests")] - public class Update + public class Update { private readonly IntegrationFixture fixture; @@ -32,7 +33,7 @@ public void SimpleUpdate() sync.Proceed(); }, messageId, - this.fixture.Config.TestChannel, + this.fixture.Config.TestChannelId, "[changed]", attachments: SlackMother.SomeAttachments, as_user: true); @@ -56,7 +57,7 @@ private string PostedMessage(SlackSocketClient client) Assert.True(response.ok, "Error while posting message to channel. "); sync.Proceed(); }, - this.fixture.Config.TestChannel, + this.fixture.Config.TestChannelId, "Hi there!", as_user: true); } diff --git a/SlackAPI.Tests/Users.cs b/SlackAPI.Tests/Users.cs index 99ec23f..ffa5563 100644 --- a/SlackAPI.Tests/Users.cs +++ b/SlackAPI.Tests/Users.cs @@ -1,6 +1,6 @@ -using System.Linq; -using SlackAPI.Tests.Configuration; +using SlackAPI.Tests.Configuration; using SlackAPI.Tests.Helpers; +using System.Linq; using Xunit; namespace SlackAPI.Tests @@ -14,6 +14,7 @@ public Users(IntegrationFixture fixture) { this.fixture = fixture; } + [Fact] public void UserList() { diff --git a/SlackAPI/Attachment.cs b/SlackAPI/Attachment.cs index 25ae63f..30fb8b7 100644 --- a/SlackAPI/Attachment.cs +++ b/SlackAPI/Attachment.cs @@ -14,7 +14,7 @@ public class Attachment public string title_link; public string text; public Field[] fields; - + public string image_url; public string thumb_url; public string[] mrkdwn_in; @@ -24,7 +24,8 @@ public class Attachment public string footer_icon; } - public class Field{ + public class Field + { public string title; public string value; public bool @short; diff --git a/SlackAPI/Bot.cs b/SlackAPI/Bot.cs index 4c6f900..d941a09 100644 --- a/SlackAPI/Bot.cs +++ b/SlackAPI/Bot.cs @@ -1,10 +1,8 @@ -using System; - -namespace SlackAPI +namespace SlackAPI { public class Bot { - public string emoji; + public string emoji; public string image_24; public string image_32; public string image_48; diff --git a/SlackAPI/Channel.cs b/SlackAPI/Channel.cs index 7335e8b..21ea977 100644 --- a/SlackAPI/Channel.cs +++ b/SlackAPI/Channel.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { public class Channel : Conversation { diff --git a/SlackAPI/ContextMessage.cs b/SlackAPI/ContextMessage.cs index 764c17a..f1347a3 100644 --- a/SlackAPI/ContextMessage.cs +++ b/SlackAPI/ContextMessage.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { public class ContextMessage : Message { diff --git a/SlackAPI/Conversation.cs b/SlackAPI/Conversation.cs index def8d1a..5b5c013 100644 --- a/SlackAPI/Conversation.cs +++ b/SlackAPI/Conversation.cs @@ -1,8 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace SlackAPI { diff --git a/SlackAPI/DirectMessageConversation.cs b/SlackAPI/DirectMessageConversation.cs index 2241fe6..9debbd3 100644 --- a/SlackAPI/DirectMessageConversation.cs +++ b/SlackAPI/DirectMessageConversation.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { public class DirectMessageConversation : Conversation { diff --git a/SlackAPI/Extensions.cs b/SlackAPI/Extensions.cs index 194a948..04ecdc3 100644 --- a/SlackAPI/Extensions.cs +++ b/SlackAPI/Extensions.cs @@ -1,6 +1,6 @@ -using System; +using Newtonsoft.Json; +using System; using System.Collections.Generic; -using Newtonsoft.Json; namespace SlackAPI { @@ -36,7 +36,7 @@ public static object Deserialize(this string data, Type type) private static JsonSerializerSettings CreateSettings() { - JsonSerializerSettings settings = new JsonSerializerSettings(); + var settings = new JsonSerializerSettings(); settings.Converters = Converters; return settings; diff --git a/SlackAPI/JavascriptBotsToArray.cs b/SlackAPI/JavascriptBotsToArray.cs index c8d0a38..565f1a0 100644 --- a/SlackAPI/JavascriptBotsToArray.cs +++ b/SlackAPI/JavascriptBotsToArray.cs @@ -1,8 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace SlackAPI { @@ -15,12 +12,12 @@ public override bool CanConvert(Type objectType) public override object ReadJson(Newtonsoft.Json.JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer) { - List bots = new List(); + var bots = new List(); int d = reader.Depth; while (reader.Read() && reader.Depth > d) { - Bot current = new Bot(); + var current = new Bot(); int depth = reader.Depth; current.name = reader.Value.ToString(); diff --git a/SlackAPI/JavascriptDateTimeConverter.cs b/SlackAPI/JavascriptDateTimeConverter.cs index d70d374..7d6c73e 100644 --- a/SlackAPI/JavascriptDateTimeConverter.cs +++ b/SlackAPI/JavascriptDateTimeConverter.cs @@ -1,9 +1,5 @@ using System; -using System.Collections.Generic; using System.Globalization; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace SlackAPI { @@ -16,12 +12,12 @@ public override bool CanConvert(Type objectType) public override object ReadJson(Newtonsoft.Json.JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer) { - decimal value = decimal.Parse(reader.Value.ToString(), CultureInfo.InvariantCulture); - DateTime res = new DateTime(621355968000000000 + (long)(value * 10000000m)).ToLocalTime(); + var value = decimal.Parse(reader.Value.ToString(), CultureInfo.InvariantCulture); + var res = new DateTime(621355968000000000 + (long)(value * 10000000m)).ToLocalTime(); System.Diagnostics.Debug.Assert( Decimal.Equals( - Decimal.Parse(res.ToProperTimeStamp()), - Decimal.Parse(reader.Value.ToString(), CultureInfo.InvariantCulture)), + Decimal.Parse(res.ToProperTimeStamp()), + Decimal.Parse(reader.Value.ToString(), CultureInfo.InvariantCulture)), "Precision loss :("); return res; } diff --git a/SlackAPI/Message.cs b/SlackAPI/Message.cs index d829245..d9b11d6 100644 --- a/SlackAPI/Message.cs +++ b/SlackAPI/Message.cs @@ -1,8 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace SlackAPI { diff --git a/SlackAPI/MimeTypes.cs b/SlackAPI/MimeTypes.cs index 9fb7794..172c856 100644 --- a/SlackAPI/MimeTypes.cs +++ b/SlackAPI/MimeTypes.cs @@ -1,8 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace SlackAPI { @@ -10,498 +7,498 @@ public static class MimeType { private static Dictionary MimeTypeDict = new Dictionary() - { - { "ez", "application/andrew-inset" }, - { "anx", "application/annodex" }, - { "atom", "application/atom+xml" }, - { "atomcat", "application/atomcat+xml" }, - { "atomsrv", "application/atomserv+xml" }, - { "lin", "application/bbolin" }, - { "cap", "application/cap" }, - { "pcap", "application/cap" }, - { "cu", "application/cu-seeme" }, - { "davmount", "application/davmount+xml" }, - { "tsp", "application/dsptype" }, - { "es", "application/ecmascript" }, - { "spl", "application/futuresplash" }, - { "hta", "application/hta" }, - { "jar", "application/java-archive" }, - { "ser", "application/java-serialized-object" }, - { "class", "application/java-vm" }, - { "js", "application/javascript" }, - { "json", "application/json" }, - { "m3g", "application/m3g" }, - { "hqx", "application/mac-binhex40" }, - { "cpt", "application/mac-compactpro" }, - { "nb", "application/mathematica" }, - { "nbp", "application/mathematica" }, - { "mdb", "application/msaccess" }, - { "doc", "application/msword" }, - { "dot", "application/msword" }, - { "mxf", "application/mxf" }, - { "bin", "application/octet-stream" }, - { "oda", "application/oda" }, - { "ogx", "application/ogg" }, - { "pdf", "application/pdf" }, - { "key", "application/pgp-keys" }, - { "pgp", "application/pgp-signature" }, - { "prf", "application/pics-rules" }, - { "ps", "application/postscript" }, - { "ai", "application/postscript" }, - { "eps", "application/postscript" }, - { "epsi", "application/postscript" }, - { "epsf", "application/postscript" }, - { "eps2", "application/postscript" }, - { "eps3", "application/postscript" }, - { "rar", "application/rar" }, - { "rdf", "application/rdf+xml" }, - { "rss", "application/rss+xml" }, - { "rtf", "application/rtf" }, - { "smi", "application/smil" }, - { "smil", "application/smil" }, - { "xhtml", "application/xhtml+xml" }, - { "xht", "application/xhtml+xml" }, - { "xml", "application/xml" }, - { "xsl", "application/xml" }, - { "xsd", "application/xml" }, - { "xspf", "application/xspf+xml" }, - { "zip", "application/zip" }, - { "apk", "application/vnd.android.package-archive" }, - { "cdy", "application/vnd.cinderella" }, - { "kml", "application/vnd.google-earth.kml+xml" }, - { "kmz", "application/vnd.google-earth.kmz" }, - { "xul", "application/vnd.mozilla.xul+xml" }, - { "xls", "application/vnd.ms-excel" }, - { "xlb", "application/vnd.ms-excel" }, - { "xlt", "application/vnd.ms-excel" }, - { "cat", "application/vnd.ms-pki.seccat" }, - { "stl", "application/vnd.ms-pki.stl" }, - { "ppt", "application/vnd.ms-powerpoint" }, - { "pps", "application/vnd.ms-powerpoint" }, - { "odc", "application/vnd.oasis.opendocument.chart" }, - { "odb", "application/vnd.oasis.opendocument.database" }, - { "odf", "application/vnd.oasis.opendocument.formula" }, - { "odg", "application/vnd.oasis.opendocument.graphics" }, - { "otg", "application/vnd.oasis.opendocument.graphics-template" }, - { "odi", "application/vnd.oasis.opendocument.image" }, - { "odp", "application/vnd.oasis.opendocument.presentation" }, - { "otp", "application/vnd.oasis.opendocument.presentation-template" }, - { "ods", "application/vnd.oasis.opendocument.spreadsheet" }, - { "ots", "application/vnd.oasis.opendocument.spreadsheet-template" }, - { "odt", "application/vnd.oasis.opendocument.text" }, - { "odm", "application/vnd.oasis.opendocument.text-master" }, - { "ott", "application/vnd.oasis.opendocument.text-template" }, - { "oth", "application/vnd.oasis.opendocument.text-web" }, - { "xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }, - { "xltx", "application/vnd.openxmlformats-officedocument.spreadsheetml.template" }, - { "pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation" }, - { "ppsx", "application/vnd.openxmlformats-officedocument.presentationml.slideshow" }, - { "potx", "application/vnd.openxmlformats-officedocument.presentationml.template" }, - { "docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document" }, - { "dotx", "application/vnd.openxmlformats-officedocument.wordprocessingml.template" }, - { "cod", "application/vnd.rim.cod" }, - { "mmf", "application/vnd.smaf" }, - { "sdc", "application/vnd.stardivision.calc" }, - { "sds", "application/vnd.stardivision.chart" }, - { "sda", "application/vnd.stardivision.draw" }, - { "sdd", "application/vnd.stardivision.impress" }, - { "sdf", "application/vnd.stardivision.math" }, - { "sdw", "application/vnd.stardivision.writer" }, - { "sgl", "application/vnd.stardivision.writer-global" }, - { "sxc", "application/vnd.sun.xml.calc" }, - { "stc", "application/vnd.sun.xml.calc.template" }, - { "sxd", "application/vnd.sun.xml.draw" }, - { "std", "application/vnd.sun.xml.draw.template" }, - { "sxi", "application/vnd.sun.xml.impress" }, - { "sti", "application/vnd.sun.xml.impress.template" }, - { "sxm", "application/vnd.sun.xml.math" }, - { "sxw", "application/vnd.sun.xml.writer" }, - { "sxg", "application/vnd.sun.xml.writer.global" }, - { "stw", "application/vnd.sun.xml.writer.template" }, - { "sis", "application/vnd.symbian.install" }, - { "vsd", "application/vnd.visio" }, - { "wbxml", "application/vnd.wap.wbxml" }, - { "wmlc", "application/vnd.wap.wmlc" }, - { "wmlsc", "application/vnd.wap.wmlscriptc" }, - { "wpd", "application/vnd.wordperfect" }, - { "wp5", "application/vnd.wordperfect5.1" }, - { "wk", "application/x-123" }, - { "7z", "application/x-7z-compressed" }, - { "abw", "application/x-abiword" }, - { "dmg", "application/x-apple-diskimage" }, - { "bcpio", "application/x-bcpio" }, - { "torrent", "application/x-bittorrent" }, - { "cab", "application/x-cab" }, - { "cbr", "application/x-cbr" }, - { "cbz", "application/x-cbz" }, - { "cdf", "application/x-cdf" }, - { "cda", "application/x-cdf" }, - { "vcd", "application/x-cdlink" }, - { "pgn", "application/x-chess-pgn" }, - { "cpio", "application/x-cpio" }, - { "csh", "application/x-csh" }, - { "deb", "application/x-debian-package" }, - { "udeb", "application/x-debian-package" }, - { "dcr", "application/x-director" }, - { "dir", "application/x-director" }, - { "dxr", "application/x-director" }, - { "dms", "application/x-dms" }, - { "wad", "application/x-doom" }, - { "dvi", "application/x-dvi" }, - { "rhtml", "application/x-httpd-eruby" }, - { "pfa", "application/x-font" }, - { "pfb", "application/x-font" }, - { "gsf", "application/x-font" }, - { "pcf", "application/x-font" }, - { "pcf.Z", "application/x-font" }, - { "mm", "application/x-freemind" }, - { "gnumeric", "application/x-gnumeric" }, - { "sgf", "application/x-go-sgf" }, - { "gcf", "application/x-graphing-calculator" }, - { "gtar", "application/x-gtar" }, - { "tgz", "application/x-gtar" }, - { "taz", "application/x-gtar" }, - { "hdf", "application/x-hdf" }, - { "phtml", "application/x-httpd-php" }, - { "pht", "application/x-httpd-php" }, - { "php", "application/x-httpd-php" }, - { "phps", "application/x-httpd-php-source" }, - { "php3", "application/x-httpd-php3" }, - { "php3p", "application/x-httpd-php3-preprocessed" }, - { "php4", "application/x-httpd-php4" }, - { "php5", "application/x-httpd-php5" }, - { "ica", "application/x-ica" }, - { "info", "application/x-info" }, - { "ins", "application/x-internet-signup" }, - { "isp", "application/x-internet-signup" }, - { "iii", "application/x-iphone" }, - { "iso", "application/x-iso9660-image" }, - { "jam", "application/x-jam" }, - { "jnlp", "application/x-java-jnlp-file" }, - { "jmz", "application/x-jmol" }, - { "chrt", "application/x-kchart" }, - { "kil", "application/x-killustrator" }, - { "skp", "application/x-koan" }, - { "skd", "application/x-koan" }, - { "skt", "application/x-koan" }, - { "skm", "application/x-koan" }, - { "kpr", "application/x-kpresenter" }, - { "kpt", "application/x-kpresenter" }, - { "ksp", "application/x-kspread" }, - { "kwd", "application/x-kword" }, - { "kwt", "application/x-kword" }, - { "latex", "application/x-latex" }, - { "lha", "application/x-lha" }, - { "lyx", "application/x-lyx" }, - { "lzh", "application/x-lzh" }, - { "lzx", "application/x-lzx" }, - { "frm", "application/x-maker" }, - { "maker", "application/x-maker" }, - { "frame", "application/x-maker" }, - { "fm", "application/x-maker" }, - { "fb", "application/x-maker" }, - { "book", "application/x-maker" }, - { "fbdoc", "application/x-maker" }, - { "mif", "application/x-mif" }, - { "wmd", "application/x-ms-wmd" }, - { "wmz", "application/x-ms-wmz" }, - { "com", "application/x-msdos-program" }, - { "exe", "application/x-msdos-program" }, - { "bat", "application/x-msdos-program" }, - { "dll", "application/x-msdos-program" }, - { "msi", "application/x-msi" }, - { "nc", "application/x-netcdf" }, - { "pac", "application/x-ns-proxy-autoconfig" }, - { "dat", "application/x-ns-proxy-autoconfig" }, - { "nwc", "application/x-nwc" }, - { "o", "application/x-object" }, - { "oza", "application/x-oz-application" }, - { "p7r", "application/x-pkcs7-certreqresp" }, - { "crl", "application/x-pkcs7-crl" }, - { "pyc", "application/x-python-code" }, - { "pyo", "application/x-python-code" }, - { "qgs", "application/x-qgis" }, - { "shp", "application/x-qgis" }, - { "shx", "application/x-qgis" }, - { "qtl", "application/x-quicktimeplayer" }, - { "rpm", "application/x-redhat-package-manager" }, - { "rb", "application/x-ruby" }, - { "sh", "application/x-sh" }, - { "shar", "application/x-shar" }, - { "swf", "application/x-shockwave-flash" }, - { "swfl", "application/x-shockwave-flash" }, - { "scr", "application/x-silverlight" }, - { "sit", "application/x-stuffit" }, - { "sitx", "application/x-stuffit" }, - { "sv4cpio", "application/x-sv4cpio" }, - { "sv4crc", "application/x-sv4crc" }, - { "tar", "application/x-tar" }, - { "tcl", "application/x-tcl" }, - { "gf", "application/x-tex-gf" }, - { "pk", "application/x-tex-pk" }, - { "texinfo", "application/x-texinfo" }, - { "texi", "application/x-texinfo" }, - { "~", "application/x-trash" }, - { "%", "application/x-trash" }, - { "bak", "application/x-trash" }, - { "old", "application/x-trash" }, - { "sik", "application/x-trash" }, - { "t", "application/x-troff" }, - { "tr", "application/x-troff" }, - { "roff", "application/x-troff" }, - { "man", "application/x-troff-man" }, - { "me", "application/x-troff-me" }, - { "ms", "application/x-troff-ms" }, - { "ustar", "application/x-ustar" }, - { "src", "application/x-wais-source" }, - { "wz", "application/x-wingz" }, - { "crt", "application/x-x509-ca-cert" }, - { "xcf", "application/x-xcf" }, - { "fig", "application/x-xfig" }, - { "xpi", "application/x-xpinstall" }, - { "amr", "audio/amr" }, - { "awb", "audio/amr-wb" }, - { "axa", "audio/annodex" }, - { "au", "audio/basic" }, - { "snd", "audio/basic" }, - { "flac", "audio/flac" }, - { "mid", "audio/midi" }, - { "midi", "audio/midi" }, - { "kar", "audio/midi" }, - { "mpga", "audio/mpeg" }, - { "mpega", "audio/mpeg" }, - { "mp2", "audio/mpeg" }, - { "mp3", "audio/mpeg" }, - { "m4a", "audio/mpeg" }, - { "m3u", "audio/mpegurl" }, - { "oga", "audio/ogg" }, - { "ogg", "audio/ogg" }, - { "spx", "audio/ogg" }, - { "sid", "audio/prs.sid" }, - { "aif", "audio/x-aiff" }, - { "aiff", "audio/x-aiff" }, - { "aifc", "audio/x-aiff" }, - { "gsm", "audio/x-gsm" }, - { "wma", "audio/x-ms-wma" }, - { "wax", "audio/x-ms-wax" }, - { "ra", "audio/x-pn-realaudio" }, - { "rm", "audio/x-pn-realaudio" }, - { "ram", "audio/x-pn-realaudio" }, - { "pls", "audio/x-scpls" }, - { "sd2", "audio/x-sd2" }, - { "wav", "audio/x-wav" }, - { "alc", "chemical/x-alchemy" }, - { "cac", "chemical/x-cache" }, - { "cache", "chemical/x-cache" }, - { "csf", "chemical/x-cache-csf" }, - { "cbin", "chemical/x-cactvs-binary" }, - { "cascii", "chemical/x-cactvs-binary" }, - { "ctab", "chemical/x-cactvs-binary" }, - { "cdx", "chemical/x-cdx" }, - { "cer", "chemical/x-cerius" }, - { "c3d", "chemical/x-chem3d" }, - { "chm", "chemical/x-chemdraw" }, - { "cif", "chemical/x-cif" }, - { "cmdf", "chemical/x-cmdf" }, - { "cml", "chemical/x-cml" }, - { "cpa", "chemical/x-compass" }, - { "bsd", "chemical/x-crossfire" }, - { "csml", "chemical/x-csml" }, - { "csm", "chemical/x-csml" }, - { "ctx", "chemical/x-ctx" }, - { "cxf", "chemical/x-cxf" }, - { "cef", "chemical/x-cxf" }, - { "emb", "chemical/x-embl-dl-nucleotide" }, - { "embl", "chemical/x-embl-dl-nucleotide" }, - { "spc", "chemical/x-galactic-spc" }, - { "inp", "chemical/x-gamess-input" }, - { "gam", "chemical/x-gamess-input" }, - { "gamin", "chemical/x-gamess-input" }, - { "fch", "chemical/x-gaussian-checkpoint" }, - { "fchk", "chemical/x-gaussian-checkpoint" }, - { "cub", "chemical/x-gaussian-cube" }, - { "gau", "chemical/x-gaussian-input" }, - { "gjc", "chemical/x-gaussian-input" }, - { "gjf", "chemical/x-gaussian-input" }, - { "gal", "chemical/x-gaussian-log" }, - { "gcg", "chemical/x-gcg8-sequence" }, - { "gen", "chemical/x-genbank" }, - { "hin", "chemical/x-hin" }, - { "istr", "chemical/x-isostar" }, - { "ist", "chemical/x-isostar" }, - { "jdx", "chemical/x-jcamp-dx" }, - { "dx", "chemical/x-jcamp-dx" }, - { "kin", "chemical/x-kinemage" }, - { "mcm", "chemical/x-macmolecule" }, - { "mmd", "chemical/x-macromodel-input" }, - { "mmod", "chemical/x-macromodel-input" }, - { "mol", "chemical/x-mdl-molfile" }, - { "rd", "chemical/x-mdl-rdfile" }, - { "rxn", "chemical/x-mdl-rxnfile" }, - { "sd", "chemical/x-mdl-sdfile" }, - { "tgf", "chemical/x-mdl-tgf" }, - { "mcif", "chemical/x-mmcif" }, - { "mol2", "chemical/x-mol2" }, - { "b", "chemical/x-molconn-Z" }, - { "gpt", "chemical/x-mopac-graph" }, - { "mop", "chemical/x-mopac-input" }, - { "mopcrt", "chemical/x-mopac-input" }, - { "mpc", "chemical/x-mopac-input" }, - { "zmt", "chemical/x-mopac-input" }, - { "moo", "chemical/x-mopac-out" }, - { "mvb", "chemical/x-mopac-vib" }, - { "asn", "chemical/x-ncbi-asn1" }, - { "prt", "chemical/x-ncbi-asn1-ascii" }, - { "ent", "chemical/x-ncbi-asn1-ascii" }, - { "val", "chemical/x-ncbi-asn1-binary" }, - { "aso", "chemical/x-ncbi-asn1-binary" }, - { "pdb", "chemical/x-pdb" }, - { "ros", "chemical/x-rosdal" }, - { "sw", "chemical/x-swissprot" }, - { "vms", "chemical/x-vamas-iso14976" }, - { "vmd", "chemical/x-vmd" }, - { "xtel", "chemical/x-xtel" }, - { "xyz", "chemical/x-xyz" }, - { "gif", "image/gif" }, - { "ief", "image/ief" }, - { "jpeg", "image/jpeg" }, - { "jpg", "image/jpeg" }, - { "jpe", "image/jpeg" }, - { "pcx", "image/pcx" }, - { "png", "image/png" }, - { "svg", "image/svg+xml" }, - { "svgz", "image/svg+xml" }, - { "tiff", "image/tiff" }, - { "tif", "image/tiff" }, - { "djvu", "image/vnd.djvu" }, - { "djv", "image/vnd.djvu" }, - { "wbmp", "image/vnd.wap.wbmp" }, - { "cr2", "image/x-canon-cr2" }, - { "crw", "image/x-canon-crw" }, - { "ras", "image/x-cmu-raster" }, - { "cdr", "image/x-coreldraw" }, - { "pat", "image/x-coreldrawpattern" }, - { "cdt", "image/x-coreldrawtemplate" }, - { "erf", "image/x-epson-erf" }, - { "ico", "image/x-icon" }, - { "art", "image/x-jg" }, - { "jng", "image/x-jng" }, - { "bmp", "image/x-ms-bmp" }, - { "nef", "image/x-nikon-nef" }, - { "orf", "image/x-olympus-orf" }, - { "psd", "image/x-photoshop" }, - { "pnm", "image/x-portable-anymap" }, - { "pbm", "image/x-portable-bitmap" }, - { "pgm", "image/x-portable-graymap" }, - { "ppm", "image/x-portable-pixmap" }, - { "rgb", "image/x-rgb" }, - { "xbm", "image/x-xbitmap" }, - { "xpm", "image/x-xpixmap" }, - { "xwd", "image/x-xwindowdump" }, - { "eml", "message/rfc822" }, - { "igs", "model/iges" }, - { "iges", "model/iges" }, - { "msh", "model/mesh" }, - { "mesh", "model/mesh" }, - { "silo", "model/mesh" }, - { "wrl", "model/vrml" }, - { "vrml", "model/vrml" }, - { "x3dv", "model/x3d+vrml" }, - { "x3d", "model/x3d+xml" }, - { "x3db", "model/x3d+binary" }, - { "manifest", "text/cache-manifest" }, - { "ics", "text/calendar" }, - { "icz", "text/calendar" }, - { "css", "text/css" }, - { "csv", "text/csv" }, - { "323", "text/h323" }, - { "html", "text/html" }, - { "htm", "text/html" }, - { "shtml", "text/html" }, - { "uls", "text/iuls" }, - { "mml", "text/mathml" }, - { "asc", "text/plain" }, - { "txt", "text/plain" }, - { "text", "text/plain" }, - { "pot", "text/plain" }, - { "brf", "text/plain" }, - { "rtx", "text/richtext" }, - { "sct", "text/scriptlet" }, - { "wsc", "text/scriptlet" }, - { "tm", "text/texmacs" }, - { "ts", "text/texmacs" }, - { "tsv", "text/tab-separated-values" }, - { "jad", "text/vnd.sun.j2me.app-descriptor" }, - { "wml", "text/vnd.wap.wml" }, - { "wmls", "text/vnd.wap.wmlscript" }, - { "bib", "text/x-bibtex" }, - { "boo", "text/x-boo" }, - { "h++", "text/x-c++hdr" }, - { "hpp", "text/x-c++hdr" }, - { "hxx", "text/x-c++hdr" }, - { "hh", "text/x-c++hdr" }, - { "c++", "text/x-c++src" }, - { "cpp", "text/x-c++src" }, - { "cxx", "text/x-c++src" }, - { "cc", "text/x-c++src" }, - { "h", "text/x-chdr" }, - { "htc", "text/x-component" }, - { "c", "text/x-csrc" }, - { "d", "text/x-dsrc" }, - { "diff", "text/x-diff" }, - { "patch", "text/x-diff" }, - { "hs", "text/x-haskell" }, - { "java", "text/x-java" }, - { "lhs", "text/x-literate-haskell" }, - { "moc", "text/x-moc" }, - { "p", "text/x-pascal" }, - { "pas", "text/x-pascal" }, - { "gcd", "text/x-pcs-gcd" }, - { "pl", "text/x-perl" }, - { "pm", "text/x-perl" }, - { "py", "text/x-python" }, - { "scala", "text/x-scala" }, - { "etx", "text/x-setext" }, - { "tk", "text/x-tcl" }, - { "tex", "text/x-tex" }, - { "ltx", "text/x-tex" }, - { "sty", "text/x-tex" }, - { "cls", "text/x-tex" }, - { "vcs", "text/x-vcalendar" }, - { "vcf", "text/x-vcard" }, - { "3gp", "video/3gpp" }, - { "axv", "video/annodex" }, - { "dl", "video/dl" }, - { "dif", "video/dv" }, - { "dv", "video/dv" }, - { "fli", "video/fli" }, - { "gl", "video/gl" }, - { "mpeg", "video/mpeg" }, - { "mpg", "video/mpeg" }, - { "mpe", "video/mpeg" }, - { "mp4", "video/mp4" }, - { "qt", "video/quicktime" }, - { "mov", "video/quicktime" }, - { "ogv", "video/ogg" }, - { "mxu", "video/vnd.mpegurl" }, - { "flv", "video/x-flv" }, - { "lsf", "video/x-la-asf" }, - { "lsx", "video/x-la-asf" }, - { "mng", "video/x-mng" }, - { "asf", "video/x-ms-asf" }, - { "asx", "video/x-ms-asf" }, - { "wm", "video/x-ms-wm" }, - { "wmv", "video/x-ms-wmv" }, - { "wmx", "video/x-ms-wmx" }, - { "wvx", "video/x-ms-wvx" }, - { "avi", "video/x-msvideo" }, - { "movie", "video/x-sgi-movie" }, - { "mpv", "video/x-matroska" }, - { "mkv", "video/x-matroska" }, - { "ice", "x-conference/x-cooltalk" }, - { "sisx", "x-epoc/x-sisx-app" }, - { "vrm", "x-world/x-vrml" } - }; + { + { "ez", "application/andrew-inset" }, + { "anx", "application/annodex" }, + { "atom", "application/atom+xml" }, + { "atomcat", "application/atomcat+xml" }, + { "atomsrv", "application/atomserv+xml" }, + { "lin", "application/bbolin" }, + { "cap", "application/cap" }, + { "pcap", "application/cap" }, + { "cu", "application/cu-seeme" }, + { "davmount", "application/davmount+xml" }, + { "tsp", "application/dsptype" }, + { "es", "application/ecmascript" }, + { "spl", "application/futuresplash" }, + { "hta", "application/hta" }, + { "jar", "application/java-archive" }, + { "ser", "application/java-serialized-object" }, + { "class", "application/java-vm" }, + { "js", "application/javascript" }, + { "json", "application/json" }, + { "m3g", "application/m3g" }, + { "hqx", "application/mac-binhex40" }, + { "cpt", "application/mac-compactpro" }, + { "nb", "application/mathematica" }, + { "nbp", "application/mathematica" }, + { "mdb", "application/msaccess" }, + { "doc", "application/msword" }, + { "dot", "application/msword" }, + { "mxf", "application/mxf" }, + { "bin", "application/octet-stream" }, + { "oda", "application/oda" }, + { "ogx", "application/ogg" }, + { "pdf", "application/pdf" }, + { "key", "application/pgp-keys" }, + { "pgp", "application/pgp-signature" }, + { "prf", "application/pics-rules" }, + { "ps", "application/postscript" }, + { "ai", "application/postscript" }, + { "eps", "application/postscript" }, + { "epsi", "application/postscript" }, + { "epsf", "application/postscript" }, + { "eps2", "application/postscript" }, + { "eps3", "application/postscript" }, + { "rar", "application/rar" }, + { "rdf", "application/rdf+xml" }, + { "rss", "application/rss+xml" }, + { "rtf", "application/rtf" }, + { "smi", "application/smil" }, + { "smil", "application/smil" }, + { "xhtml", "application/xhtml+xml" }, + { "xht", "application/xhtml+xml" }, + { "xml", "application/xml" }, + { "xsl", "application/xml" }, + { "xsd", "application/xml" }, + { "xspf", "application/xspf+xml" }, + { "zip", "application/zip" }, + { "apk", "application/vnd.android.package-archive" }, + { "cdy", "application/vnd.cinderella" }, + { "kml", "application/vnd.google-earth.kml+xml" }, + { "kmz", "application/vnd.google-earth.kmz" }, + { "xul", "application/vnd.mozilla.xul+xml" }, + { "xls", "application/vnd.ms-excel" }, + { "xlb", "application/vnd.ms-excel" }, + { "xlt", "application/vnd.ms-excel" }, + { "cat", "application/vnd.ms-pki.seccat" }, + { "stl", "application/vnd.ms-pki.stl" }, + { "ppt", "application/vnd.ms-powerpoint" }, + { "pps", "application/vnd.ms-powerpoint" }, + { "odc", "application/vnd.oasis.opendocument.chart" }, + { "odb", "application/vnd.oasis.opendocument.database" }, + { "odf", "application/vnd.oasis.opendocument.formula" }, + { "odg", "application/vnd.oasis.opendocument.graphics" }, + { "otg", "application/vnd.oasis.opendocument.graphics-template" }, + { "odi", "application/vnd.oasis.opendocument.image" }, + { "odp", "application/vnd.oasis.opendocument.presentation" }, + { "otp", "application/vnd.oasis.opendocument.presentation-template" }, + { "ods", "application/vnd.oasis.opendocument.spreadsheet" }, + { "ots", "application/vnd.oasis.opendocument.spreadsheet-template" }, + { "odt", "application/vnd.oasis.opendocument.text" }, + { "odm", "application/vnd.oasis.opendocument.text-master" }, + { "ott", "application/vnd.oasis.opendocument.text-template" }, + { "oth", "application/vnd.oasis.opendocument.text-web" }, + { "xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }, + { "xltx", "application/vnd.openxmlformats-officedocument.spreadsheetml.template" }, + { "pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation" }, + { "ppsx", "application/vnd.openxmlformats-officedocument.presentationml.slideshow" }, + { "potx", "application/vnd.openxmlformats-officedocument.presentationml.template" }, + { "docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document" }, + { "dotx", "application/vnd.openxmlformats-officedocument.wordprocessingml.template" }, + { "cod", "application/vnd.rim.cod" }, + { "mmf", "application/vnd.smaf" }, + { "sdc", "application/vnd.stardivision.calc" }, + { "sds", "application/vnd.stardivision.chart" }, + { "sda", "application/vnd.stardivision.draw" }, + { "sdd", "application/vnd.stardivision.impress" }, + { "sdf", "application/vnd.stardivision.math" }, + { "sdw", "application/vnd.stardivision.writer" }, + { "sgl", "application/vnd.stardivision.writer-global" }, + { "sxc", "application/vnd.sun.xml.calc" }, + { "stc", "application/vnd.sun.xml.calc.template" }, + { "sxd", "application/vnd.sun.xml.draw" }, + { "std", "application/vnd.sun.xml.draw.template" }, + { "sxi", "application/vnd.sun.xml.impress" }, + { "sti", "application/vnd.sun.xml.impress.template" }, + { "sxm", "application/vnd.sun.xml.math" }, + { "sxw", "application/vnd.sun.xml.writer" }, + { "sxg", "application/vnd.sun.xml.writer.global" }, + { "stw", "application/vnd.sun.xml.writer.template" }, + { "sis", "application/vnd.symbian.install" }, + { "vsd", "application/vnd.visio" }, + { "wbxml", "application/vnd.wap.wbxml" }, + { "wmlc", "application/vnd.wap.wmlc" }, + { "wmlsc", "application/vnd.wap.wmlscriptc" }, + { "wpd", "application/vnd.wordperfect" }, + { "wp5", "application/vnd.wordperfect5.1" }, + { "wk", "application/x-123" }, + { "7z", "application/x-7z-compressed" }, + { "abw", "application/x-abiword" }, + { "dmg", "application/x-apple-diskimage" }, + { "bcpio", "application/x-bcpio" }, + { "torrent", "application/x-bittorrent" }, + { "cab", "application/x-cab" }, + { "cbr", "application/x-cbr" }, + { "cbz", "application/x-cbz" }, + { "cdf", "application/x-cdf" }, + { "cda", "application/x-cdf" }, + { "vcd", "application/x-cdlink" }, + { "pgn", "application/x-chess-pgn" }, + { "cpio", "application/x-cpio" }, + { "csh", "application/x-csh" }, + { "deb", "application/x-debian-package" }, + { "udeb", "application/x-debian-package" }, + { "dcr", "application/x-director" }, + { "dir", "application/x-director" }, + { "dxr", "application/x-director" }, + { "dms", "application/x-dms" }, + { "wad", "application/x-doom" }, + { "dvi", "application/x-dvi" }, + { "rhtml", "application/x-httpd-eruby" }, + { "pfa", "application/x-font" }, + { "pfb", "application/x-font" }, + { "gsf", "application/x-font" }, + { "pcf", "application/x-font" }, + { "pcf.Z", "application/x-font" }, + { "mm", "application/x-freemind" }, + { "gnumeric", "application/x-gnumeric" }, + { "sgf", "application/x-go-sgf" }, + { "gcf", "application/x-graphing-calculator" }, + { "gtar", "application/x-gtar" }, + { "tgz", "application/x-gtar" }, + { "taz", "application/x-gtar" }, + { "hdf", "application/x-hdf" }, + { "phtml", "application/x-httpd-php" }, + { "pht", "application/x-httpd-php" }, + { "php", "application/x-httpd-php" }, + { "phps", "application/x-httpd-php-source" }, + { "php3", "application/x-httpd-php3" }, + { "php3p", "application/x-httpd-php3-preprocessed" }, + { "php4", "application/x-httpd-php4" }, + { "php5", "application/x-httpd-php5" }, + { "ica", "application/x-ica" }, + { "info", "application/x-info" }, + { "ins", "application/x-internet-signup" }, + { "isp", "application/x-internet-signup" }, + { "iii", "application/x-iphone" }, + { "iso", "application/x-iso9660-image" }, + { "jam", "application/x-jam" }, + { "jnlp", "application/x-java-jnlp-file" }, + { "jmz", "application/x-jmol" }, + { "chrt", "application/x-kchart" }, + { "kil", "application/x-killustrator" }, + { "skp", "application/x-koan" }, + { "skd", "application/x-koan" }, + { "skt", "application/x-koan" }, + { "skm", "application/x-koan" }, + { "kpr", "application/x-kpresenter" }, + { "kpt", "application/x-kpresenter" }, + { "ksp", "application/x-kspread" }, + { "kwd", "application/x-kword" }, + { "kwt", "application/x-kword" }, + { "latex", "application/x-latex" }, + { "lha", "application/x-lha" }, + { "lyx", "application/x-lyx" }, + { "lzh", "application/x-lzh" }, + { "lzx", "application/x-lzx" }, + { "frm", "application/x-maker" }, + { "maker", "application/x-maker" }, + { "frame", "application/x-maker" }, + { "fm", "application/x-maker" }, + { "fb", "application/x-maker" }, + { "book", "application/x-maker" }, + { "fbdoc", "application/x-maker" }, + { "mif", "application/x-mif" }, + { "wmd", "application/x-ms-wmd" }, + { "wmz", "application/x-ms-wmz" }, + { "com", "application/x-msdos-program" }, + { "exe", "application/x-msdos-program" }, + { "bat", "application/x-msdos-program" }, + { "dll", "application/x-msdos-program" }, + { "msi", "application/x-msi" }, + { "nc", "application/x-netcdf" }, + { "pac", "application/x-ns-proxy-autoconfig" }, + { "dat", "application/x-ns-proxy-autoconfig" }, + { "nwc", "application/x-nwc" }, + { "o", "application/x-object" }, + { "oza", "application/x-oz-application" }, + { "p7r", "application/x-pkcs7-certreqresp" }, + { "crl", "application/x-pkcs7-crl" }, + { "pyc", "application/x-python-code" }, + { "pyo", "application/x-python-code" }, + { "qgs", "application/x-qgis" }, + { "shp", "application/x-qgis" }, + { "shx", "application/x-qgis" }, + { "qtl", "application/x-quicktimeplayer" }, + { "rpm", "application/x-redhat-package-manager" }, + { "rb", "application/x-ruby" }, + { "sh", "application/x-sh" }, + { "shar", "application/x-shar" }, + { "swf", "application/x-shockwave-flash" }, + { "swfl", "application/x-shockwave-flash" }, + { "scr", "application/x-silverlight" }, + { "sit", "application/x-stuffit" }, + { "sitx", "application/x-stuffit" }, + { "sv4cpio", "application/x-sv4cpio" }, + { "sv4crc", "application/x-sv4crc" }, + { "tar", "application/x-tar" }, + { "tcl", "application/x-tcl" }, + { "gf", "application/x-tex-gf" }, + { "pk", "application/x-tex-pk" }, + { "texinfo", "application/x-texinfo" }, + { "texi", "application/x-texinfo" }, + { "~", "application/x-trash" }, + { "%", "application/x-trash" }, + { "bak", "application/x-trash" }, + { "old", "application/x-trash" }, + { "sik", "application/x-trash" }, + { "t", "application/x-troff" }, + { "tr", "application/x-troff" }, + { "roff", "application/x-troff" }, + { "man", "application/x-troff-man" }, + { "me", "application/x-troff-me" }, + { "ms", "application/x-troff-ms" }, + { "ustar", "application/x-ustar" }, + { "src", "application/x-wais-source" }, + { "wz", "application/x-wingz" }, + { "crt", "application/x-x509-ca-cert" }, + { "xcf", "application/x-xcf" }, + { "fig", "application/x-xfig" }, + { "xpi", "application/x-xpinstall" }, + { "amr", "audio/amr" }, + { "awb", "audio/amr-wb" }, + { "axa", "audio/annodex" }, + { "au", "audio/basic" }, + { "snd", "audio/basic" }, + { "flac", "audio/flac" }, + { "mid", "audio/midi" }, + { "midi", "audio/midi" }, + { "kar", "audio/midi" }, + { "mpga", "audio/mpeg" }, + { "mpega", "audio/mpeg" }, + { "mp2", "audio/mpeg" }, + { "mp3", "audio/mpeg" }, + { "m4a", "audio/mpeg" }, + { "m3u", "audio/mpegurl" }, + { "oga", "audio/ogg" }, + { "ogg", "audio/ogg" }, + { "spx", "audio/ogg" }, + { "sid", "audio/prs.sid" }, + { "aif", "audio/x-aiff" }, + { "aiff", "audio/x-aiff" }, + { "aifc", "audio/x-aiff" }, + { "gsm", "audio/x-gsm" }, + { "wma", "audio/x-ms-wma" }, + { "wax", "audio/x-ms-wax" }, + { "ra", "audio/x-pn-realaudio" }, + { "rm", "audio/x-pn-realaudio" }, + { "ram", "audio/x-pn-realaudio" }, + { "pls", "audio/x-scpls" }, + { "sd2", "audio/x-sd2" }, + { "wav", "audio/x-wav" }, + { "alc", "chemical/x-alchemy" }, + { "cac", "chemical/x-cache" }, + { "cache", "chemical/x-cache" }, + { "csf", "chemical/x-cache-csf" }, + { "cbin", "chemical/x-cactvs-binary" }, + { "cascii", "chemical/x-cactvs-binary" }, + { "ctab", "chemical/x-cactvs-binary" }, + { "cdx", "chemical/x-cdx" }, + { "cer", "chemical/x-cerius" }, + { "c3d", "chemical/x-chem3d" }, + { "chm", "chemical/x-chemdraw" }, + { "cif", "chemical/x-cif" }, + { "cmdf", "chemical/x-cmdf" }, + { "cml", "chemical/x-cml" }, + { "cpa", "chemical/x-compass" }, + { "bsd", "chemical/x-crossfire" }, + { "csml", "chemical/x-csml" }, + { "csm", "chemical/x-csml" }, + { "ctx", "chemical/x-ctx" }, + { "cxf", "chemical/x-cxf" }, + { "cef", "chemical/x-cxf" }, + { "emb", "chemical/x-embl-dl-nucleotide" }, + { "embl", "chemical/x-embl-dl-nucleotide" }, + { "spc", "chemical/x-galactic-spc" }, + { "inp", "chemical/x-gamess-input" }, + { "gam", "chemical/x-gamess-input" }, + { "gamin", "chemical/x-gamess-input" }, + { "fch", "chemical/x-gaussian-checkpoint" }, + { "fchk", "chemical/x-gaussian-checkpoint" }, + { "cub", "chemical/x-gaussian-cube" }, + { "gau", "chemical/x-gaussian-input" }, + { "gjc", "chemical/x-gaussian-input" }, + { "gjf", "chemical/x-gaussian-input" }, + { "gal", "chemical/x-gaussian-log" }, + { "gcg", "chemical/x-gcg8-sequence" }, + { "gen", "chemical/x-genbank" }, + { "hin", "chemical/x-hin" }, + { "istr", "chemical/x-isostar" }, + { "ist", "chemical/x-isostar" }, + { "jdx", "chemical/x-jcamp-dx" }, + { "dx", "chemical/x-jcamp-dx" }, + { "kin", "chemical/x-kinemage" }, + { "mcm", "chemical/x-macmolecule" }, + { "mmd", "chemical/x-macromodel-input" }, + { "mmod", "chemical/x-macromodel-input" }, + { "mol", "chemical/x-mdl-molfile" }, + { "rd", "chemical/x-mdl-rdfile" }, + { "rxn", "chemical/x-mdl-rxnfile" }, + { "sd", "chemical/x-mdl-sdfile" }, + { "tgf", "chemical/x-mdl-tgf" }, + { "mcif", "chemical/x-mmcif" }, + { "mol2", "chemical/x-mol2" }, + { "b", "chemical/x-molconn-Z" }, + { "gpt", "chemical/x-mopac-graph" }, + { "mop", "chemical/x-mopac-input" }, + { "mopcrt", "chemical/x-mopac-input" }, + { "mpc", "chemical/x-mopac-input" }, + { "zmt", "chemical/x-mopac-input" }, + { "moo", "chemical/x-mopac-out" }, + { "mvb", "chemical/x-mopac-vib" }, + { "asn", "chemical/x-ncbi-asn1" }, + { "prt", "chemical/x-ncbi-asn1-ascii" }, + { "ent", "chemical/x-ncbi-asn1-ascii" }, + { "val", "chemical/x-ncbi-asn1-binary" }, + { "aso", "chemical/x-ncbi-asn1-binary" }, + { "pdb", "chemical/x-pdb" }, + { "ros", "chemical/x-rosdal" }, + { "sw", "chemical/x-swissprot" }, + { "vms", "chemical/x-vamas-iso14976" }, + { "vmd", "chemical/x-vmd" }, + { "xtel", "chemical/x-xtel" }, + { "xyz", "chemical/x-xyz" }, + { "gif", "image/gif" }, + { "ief", "image/ief" }, + { "jpeg", "image/jpeg" }, + { "jpg", "image/jpeg" }, + { "jpe", "image/jpeg" }, + { "pcx", "image/pcx" }, + { "png", "image/png" }, + { "svg", "image/svg+xml" }, + { "svgz", "image/svg+xml" }, + { "tiff", "image/tiff" }, + { "tif", "image/tiff" }, + { "djvu", "image/vnd.djvu" }, + { "djv", "image/vnd.djvu" }, + { "wbmp", "image/vnd.wap.wbmp" }, + { "cr2", "image/x-canon-cr2" }, + { "crw", "image/x-canon-crw" }, + { "ras", "image/x-cmu-raster" }, + { "cdr", "image/x-coreldraw" }, + { "pat", "image/x-coreldrawpattern" }, + { "cdt", "image/x-coreldrawtemplate" }, + { "erf", "image/x-epson-erf" }, + { "ico", "image/x-icon" }, + { "art", "image/x-jg" }, + { "jng", "image/x-jng" }, + { "bmp", "image/x-ms-bmp" }, + { "nef", "image/x-nikon-nef" }, + { "orf", "image/x-olympus-orf" }, + { "psd", "image/x-photoshop" }, + { "pnm", "image/x-portable-anymap" }, + { "pbm", "image/x-portable-bitmap" }, + { "pgm", "image/x-portable-graymap" }, + { "ppm", "image/x-portable-pixmap" }, + { "rgb", "image/x-rgb" }, + { "xbm", "image/x-xbitmap" }, + { "xpm", "image/x-xpixmap" }, + { "xwd", "image/x-xwindowdump" }, + { "eml", "message/rfc822" }, + { "igs", "model/iges" }, + { "iges", "model/iges" }, + { "msh", "model/mesh" }, + { "mesh", "model/mesh" }, + { "silo", "model/mesh" }, + { "wrl", "model/vrml" }, + { "vrml", "model/vrml" }, + { "x3dv", "model/x3d+vrml" }, + { "x3d", "model/x3d+xml" }, + { "x3db", "model/x3d+binary" }, + { "manifest", "text/cache-manifest" }, + { "ics", "text/calendar" }, + { "icz", "text/calendar" }, + { "css", "text/css" }, + { "csv", "text/csv" }, + { "323", "text/h323" }, + { "html", "text/html" }, + { "htm", "text/html" }, + { "shtml", "text/html" }, + { "uls", "text/iuls" }, + { "mml", "text/mathml" }, + { "asc", "text/plain" }, + { "txt", "text/plain" }, + { "text", "text/plain" }, + { "pot", "text/plain" }, + { "brf", "text/plain" }, + { "rtx", "text/richtext" }, + { "sct", "text/scriptlet" }, + { "wsc", "text/scriptlet" }, + { "tm", "text/texmacs" }, + { "ts", "text/texmacs" }, + { "tsv", "text/tab-separated-values" }, + { "jad", "text/vnd.sun.j2me.app-descriptor" }, + { "wml", "text/vnd.wap.wml" }, + { "wmls", "text/vnd.wap.wmlscript" }, + { "bib", "text/x-bibtex" }, + { "boo", "text/x-boo" }, + { "h++", "text/x-c++hdr" }, + { "hpp", "text/x-c++hdr" }, + { "hxx", "text/x-c++hdr" }, + { "hh", "text/x-c++hdr" }, + { "c++", "text/x-c++src" }, + { "cpp", "text/x-c++src" }, + { "cxx", "text/x-c++src" }, + { "cc", "text/x-c++src" }, + { "h", "text/x-chdr" }, + { "htc", "text/x-component" }, + { "c", "text/x-csrc" }, + { "d", "text/x-dsrc" }, + { "diff", "text/x-diff" }, + { "patch", "text/x-diff" }, + { "hs", "text/x-haskell" }, + { "java", "text/x-java" }, + { "lhs", "text/x-literate-haskell" }, + { "moc", "text/x-moc" }, + { "p", "text/x-pascal" }, + { "pas", "text/x-pascal" }, + { "gcd", "text/x-pcs-gcd" }, + { "pl", "text/x-perl" }, + { "pm", "text/x-perl" }, + { "py", "text/x-python" }, + { "scala", "text/x-scala" }, + { "etx", "text/x-setext" }, + { "tk", "text/x-tcl" }, + { "tex", "text/x-tex" }, + { "ltx", "text/x-tex" }, + { "sty", "text/x-tex" }, + { "cls", "text/x-tex" }, + { "vcs", "text/x-vcalendar" }, + { "vcf", "text/x-vcard" }, + { "3gp", "video/3gpp" }, + { "axv", "video/annodex" }, + { "dl", "video/dl" }, + { "dif", "video/dv" }, + { "dv", "video/dv" }, + { "fli", "video/fli" }, + { "gl", "video/gl" }, + { "mpeg", "video/mpeg" }, + { "mpg", "video/mpeg" }, + { "mpe", "video/mpeg" }, + { "mp4", "video/mp4" }, + { "qt", "video/quicktime" }, + { "mov", "video/quicktime" }, + { "ogv", "video/ogg" }, + { "mxu", "video/vnd.mpegurl" }, + { "flv", "video/x-flv" }, + { "lsf", "video/x-la-asf" }, + { "lsx", "video/x-la-asf" }, + { "mng", "video/x-mng" }, + { "asf", "video/x-ms-asf" }, + { "asx", "video/x-ms-asf" }, + { "wm", "video/x-ms-wm" }, + { "wmv", "video/x-ms-wmv" }, + { "wmx", "video/x-ms-wmx" }, + { "wvx", "video/x-ms-wvx" }, + { "avi", "video/x-msvideo" }, + { "movie", "video/x-sgi-movie" }, + { "mpv", "video/x-matroska" }, + { "mkv", "video/x-matroska" }, + { "ice", "x-conference/x-cooltalk" }, + { "sisx", "x-epoc/x-sisx-app" }, + { "vrm", "x-world/x-vrml" } + }; /// /// Returns the mime type for the requested file extension. Returns diff --git a/SlackAPI/OwnedStampedMessage.cs b/SlackAPI/OwnedStampedMessage.cs index d756e4b..ec05877 100644 --- a/SlackAPI/OwnedStampedMessage.cs +++ b/SlackAPI/OwnedStampedMessage.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { public class OwnedStampedMessage { diff --git a/SlackAPI/Preferences.cs b/SlackAPI/Preferences.cs index 92f48a5..08cd6ce 100644 --- a/SlackAPI/Preferences.cs +++ b/SlackAPI/Preferences.cs @@ -1,6 +1,4 @@ -using System; - -namespace SlackAPI +namespace SlackAPI { public class Preferences { diff --git a/SlackAPI/RPCMessages/AccessTokenResponse.cs b/SlackAPI/RPCMessages/AccessTokenResponse.cs index ebf9fb9..7a19d6c 100644 --- a/SlackAPI/RPCMessages/AccessTokenResponse.cs +++ b/SlackAPI/RPCMessages/AccessTokenResponse.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { [RequestPath("oauth.access")] public class AccessTokenResponse : Response diff --git a/SlackAPI/RPCMessages/AdminDeleteResponse.cs b/SlackAPI/RPCMessages/AdminDeleteResponse.cs new file mode 100644 index 0000000..2db14c1 --- /dev/null +++ b/SlackAPI/RPCMessages/AdminDeleteResponse.cs @@ -0,0 +1,7 @@ +namespace SlackAPI +{ + [RequestPath("users.admin.delete")] + public class AdminDeleteResponse : Response + { + } +} diff --git a/SlackAPI/RPCMessages/AdminInviteResponse.cs b/SlackAPI/RPCMessages/AdminInviteResponse.cs new file mode 100644 index 0000000..6134e25 --- /dev/null +++ b/SlackAPI/RPCMessages/AdminInviteResponse.cs @@ -0,0 +1,7 @@ +namespace SlackAPI +{ + [RequestPath("users.admin.invite")] + public class AdminInviteResponse : Response + { + } +} diff --git a/SlackAPI/RPCMessages/AdminSetInactiveResponse.cs b/SlackAPI/RPCMessages/AdminSetInactiveResponse.cs new file mode 100644 index 0000000..0495adf --- /dev/null +++ b/SlackAPI/RPCMessages/AdminSetInactiveResponse.cs @@ -0,0 +1,7 @@ +namespace SlackAPI +{ + [RequestPath("users.admin.setInactive")] + public class AdminSetInactiveResponse : Response + { + } +} diff --git a/SlackAPI/RPCMessages/AuthSigninResponse.cs b/SlackAPI/RPCMessages/AuthSigninResponse.cs index c086581..30e5fde 100644 --- a/SlackAPI/RPCMessages/AuthSigninResponse.cs +++ b/SlackAPI/RPCMessages/AuthSigninResponse.cs @@ -1,6 +1,4 @@ -using System; - -namespace SlackAPI +namespace SlackAPI { [RequestPath("auth.signin")] public class AuthSigninResponse : Response diff --git a/SlackAPI/RPCMessages/AuthStartResponse.cs b/SlackAPI/RPCMessages/AuthStartResponse.cs index 93dde36..70b7c92 100644 --- a/SlackAPI/RPCMessages/AuthStartResponse.cs +++ b/SlackAPI/RPCMessages/AuthStartResponse.cs @@ -1,6 +1,4 @@ -using System; - -namespace SlackAPI +namespace SlackAPI { [RequestPath("auth.start")] public class AuthStartResponse : Response diff --git a/SlackAPI/RPCMessages/AuthTestResponse.cs b/SlackAPI/RPCMessages/AuthTestResponse.cs index 2e9657e..7fb89e6 100644 --- a/SlackAPI/RPCMessages/AuthTestResponse.cs +++ b/SlackAPI/RPCMessages/AuthTestResponse.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { [RequestPath("auth.test", true)] public class AuthTestResponse : Response diff --git a/SlackAPI/RPCMessages/ChannelArchiveResponse.cs b/SlackAPI/RPCMessages/ChannelArchiveResponse.cs new file mode 100644 index 0000000..dc16d61 --- /dev/null +++ b/SlackAPI/RPCMessages/ChannelArchiveResponse.cs @@ -0,0 +1,7 @@ +namespace SlackAPI +{ + [RequestPath("channels.archive")] + public class ChannelArchiveResponse : Response + { + } +} diff --git a/SlackAPI/RPCMessages/ChannelCreateResponse.cs b/SlackAPI/RPCMessages/ChannelCreateResponse.cs index b527365..87c22be 100644 --- a/SlackAPI/RPCMessages/ChannelCreateResponse.cs +++ b/SlackAPI/RPCMessages/ChannelCreateResponse.cs @@ -1,6 +1,4 @@ -using System; - -namespace SlackAPI +namespace SlackAPI { [RequestPath("channels.create")] public class ChannelCreateResponse : Response diff --git a/SlackAPI/RPCMessages/ChannelInviteResponse.cs b/SlackAPI/RPCMessages/ChannelInviteResponse.cs new file mode 100644 index 0000000..adb47e7 --- /dev/null +++ b/SlackAPI/RPCMessages/ChannelInviteResponse.cs @@ -0,0 +1,7 @@ +namespace SlackAPI +{ + [RequestPath("channels.invite")] + public class ChannelInviteResponse : ChannelResponse + { + } +} diff --git a/SlackAPI/RPCMessages/ChannelListResponse.cs b/SlackAPI/RPCMessages/ChannelListResponse.cs index 22280c1..0e3d5c1 100644 --- a/SlackAPI/RPCMessages/ChannelListResponse.cs +++ b/SlackAPI/RPCMessages/ChannelListResponse.cs @@ -1,6 +1,4 @@ -using System; - -namespace SlackAPI +namespace SlackAPI { [RequestPath("channels.list")] public class ChannelListResponse : Response diff --git a/SlackAPI/RPCMessages/ChannelMessageHistory.cs b/SlackAPI/RPCMessages/ChannelMessageHistory.cs index 27fb059..b8af5cb 100644 --- a/SlackAPI/RPCMessages/ChannelMessageHistory.cs +++ b/SlackAPI/RPCMessages/ChannelMessageHistory.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { [RequestPath("channels.history")] public class ChannelMessageHistory : MessageHistory diff --git a/SlackAPI/RPCMessages/ChannelRenameResponse.cs b/SlackAPI/RPCMessages/ChannelRenameResponse.cs new file mode 100644 index 0000000..4788e9e --- /dev/null +++ b/SlackAPI/RPCMessages/ChannelRenameResponse.cs @@ -0,0 +1,10 @@ +namespace SlackAPI +{ + // https://api.slack.com/methods/channels.rename + [RequestPath("channels.rename")] + public class ChannelRenameResponse : Response + { + public string name; + public string created; + } +} diff --git a/SlackAPI/RPCMessages/ChannelResponse.cs b/SlackAPI/RPCMessages/ChannelResponse.cs new file mode 100644 index 0000000..c8e84c9 --- /dev/null +++ b/SlackAPI/RPCMessages/ChannelResponse.cs @@ -0,0 +1,7 @@ +namespace SlackAPI +{ + public class ChannelResponse : Response + { + public Channel channel; + } +} diff --git a/SlackAPI/RPCMessages/ChannelSetPurposeResponse.cs b/SlackAPI/RPCMessages/ChannelSetPurposeResponse.cs new file mode 100644 index 0000000..22cb96b --- /dev/null +++ b/SlackAPI/RPCMessages/ChannelSetPurposeResponse.cs @@ -0,0 +1,9 @@ +namespace SlackAPI +{ + // https://api.slack.com/methods/channels.setPurpose + [RequestPath("channels.setPurpose")] + public class ChannelSetPurposeResponse : Response + { + public string purpose; + } +} diff --git a/SlackAPI/RPCMessages/ChannelUnarchiveResponse.cs b/SlackAPI/RPCMessages/ChannelUnarchiveResponse.cs new file mode 100644 index 0000000..7043501 --- /dev/null +++ b/SlackAPI/RPCMessages/ChannelUnarchiveResponse.cs @@ -0,0 +1,7 @@ +namespace SlackAPI +{ + [RequestPath("channels.unarchive")] + public class ChannelUnarchiveResponse : Response + { + } +} diff --git a/SlackAPI/RPCMessages/DeletedResponse.cs b/SlackAPI/RPCMessages/DeletedResponse.cs index 89b5af8..59bd7a9 100644 --- a/SlackAPI/RPCMessages/DeletedResponse.cs +++ b/SlackAPI/RPCMessages/DeletedResponse.cs @@ -1,8 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace SlackAPI { diff --git a/SlackAPI/RPCMessages/DirectMessageConversationListResponse.cs b/SlackAPI/RPCMessages/DirectMessageConversationListResponse.cs index 59746ad..8f9ccd5 100644 --- a/SlackAPI/RPCMessages/DirectMessageConversationListResponse.cs +++ b/SlackAPI/RPCMessages/DirectMessageConversationListResponse.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { [RequestPath("im.list")] public class DirectMessageConversationListResponse : Response diff --git a/SlackAPI/RPCMessages/FileInfoResponse.cs b/SlackAPI/RPCMessages/FileInfoResponse.cs index 38270a8..41455c6 100644 --- a/SlackAPI/RPCMessages/FileInfoResponse.cs +++ b/SlackAPI/RPCMessages/FileInfoResponse.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { [RequestPath("files.info")] public class FileInfoResponse : Response diff --git a/SlackAPI/RPCMessages/FileListResponse.cs b/SlackAPI/RPCMessages/FileListResponse.cs index 2771aba..6b1968b 100644 --- a/SlackAPI/RPCMessages/FileListResponse.cs +++ b/SlackAPI/RPCMessages/FileListResponse.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { [RequestPath("files.list")] public class FileListResponse : Response diff --git a/SlackAPI/RPCMessages/FileUploadResponse.cs b/SlackAPI/RPCMessages/FileUploadResponse.cs index dcf80f4..9ca74bd 100644 --- a/SlackAPI/RPCMessages/FileUploadResponse.cs +++ b/SlackAPI/RPCMessages/FileUploadResponse.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { [RequestPath("files.upload")] public class FileUploadResponse : Response diff --git a/SlackAPI/RPCMessages/FindTeamResponse.cs b/SlackAPI/RPCMessages/FindTeamResponse.cs index d0b2d09..261e84f 100644 --- a/SlackAPI/RPCMessages/FindTeamResponse.cs +++ b/SlackAPI/RPCMessages/FindTeamResponse.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { /// /// This is an undocumented response from an undocumented API. If anyone finds more info on this, please create a pull request. diff --git a/SlackAPI/RPCMessages/GroupArchiveResponse.cs b/SlackAPI/RPCMessages/GroupArchiveResponse.cs index d043012..545bfea 100644 --- a/SlackAPI/RPCMessages/GroupArchiveResponse.cs +++ b/SlackAPI/RPCMessages/GroupArchiveResponse.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { [RequestPath("groups.archive")] public class GroupArchiveResponse : Response diff --git a/SlackAPI/RPCMessages/GroupCloseResponse.cs b/SlackAPI/RPCMessages/GroupCloseResponse.cs index d0fdcd2..61ec8e6 100644 --- a/SlackAPI/RPCMessages/GroupCloseResponse.cs +++ b/SlackAPI/RPCMessages/GroupCloseResponse.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { [RequestPath("groups.close")] public class GroupCloseResponse : Response diff --git a/SlackAPI/RPCMessages/GroupCreateChildResponse.cs b/SlackAPI/RPCMessages/GroupCreateChildResponse.cs index 51d495e..59380fc 100644 --- a/SlackAPI/RPCMessages/GroupCreateChildResponse.cs +++ b/SlackAPI/RPCMessages/GroupCreateChildResponse.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { [RequestPath("groups.createChild")] public class GroupCreateChildResponse : GroupResponse diff --git a/SlackAPI/RPCMessages/GroupCreateResponse.cs b/SlackAPI/RPCMessages/GroupCreateResponse.cs index b5082e0..3fa0805 100644 --- a/SlackAPI/RPCMessages/GroupCreateResponse.cs +++ b/SlackAPI/RPCMessages/GroupCreateResponse.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { [RequestPath("groups.create")] public class GroupCreateResponse : GroupResponse diff --git a/SlackAPI/RPCMessages/GroupInviteResponse.cs b/SlackAPI/RPCMessages/GroupInviteResponse.cs index 2155178..7496678 100644 --- a/SlackAPI/RPCMessages/GroupInviteResponse.cs +++ b/SlackAPI/RPCMessages/GroupInviteResponse.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { [RequestPath("groups.invite")] public class GroupInviteResponse : GroupResponse diff --git a/SlackAPI/RPCMessages/GroupKickResponse.cs b/SlackAPI/RPCMessages/GroupKickResponse.cs index 3213fb2..e67d7db 100644 --- a/SlackAPI/RPCMessages/GroupKickResponse.cs +++ b/SlackAPI/RPCMessages/GroupKickResponse.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { [RequestPath("groups.kick")] public class GroupKickResponse : Response diff --git a/SlackAPI/RPCMessages/GroupLeaveResponse.cs b/SlackAPI/RPCMessages/GroupLeaveResponse.cs index 9c96122..93afe7e 100644 --- a/SlackAPI/RPCMessages/GroupLeaveResponse.cs +++ b/SlackAPI/RPCMessages/GroupLeaveResponse.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { [RequestPath("groups.leave")] public class GroupLeaveResponse : Response diff --git a/SlackAPI/RPCMessages/GroupListResponse.cs b/SlackAPI/RPCMessages/GroupListResponse.cs index d8ad777..99d351f 100644 --- a/SlackAPI/RPCMessages/GroupListResponse.cs +++ b/SlackAPI/RPCMessages/GroupListResponse.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { [RequestPath("groups.list")] public class GroupListResponse : Response diff --git a/SlackAPI/RPCMessages/GroupMarkResponse.cs b/SlackAPI/RPCMessages/GroupMarkResponse.cs index b4cb742..930e32f 100644 --- a/SlackAPI/RPCMessages/GroupMarkResponse.cs +++ b/SlackAPI/RPCMessages/GroupMarkResponse.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { [RequestPath("groups.mark")] public class GroupMarkResponse : Response diff --git a/SlackAPI/RPCMessages/GroupMessageHistory.cs b/SlackAPI/RPCMessages/GroupMessageHistory.cs index 5708ca8..934f364 100644 --- a/SlackAPI/RPCMessages/GroupMessageHistory.cs +++ b/SlackAPI/RPCMessages/GroupMessageHistory.cs @@ -1,6 +1,4 @@ -using System; - -namespace SlackAPI +namespace SlackAPI { [RequestPath("groups.history")] public class GroupMessageHistory : MessageHistory diff --git a/SlackAPI/RPCMessages/GroupOpenResponse.cs b/SlackAPI/RPCMessages/GroupOpenResponse.cs index 70c2ffc..23c307b 100644 --- a/SlackAPI/RPCMessages/GroupOpenResponse.cs +++ b/SlackAPI/RPCMessages/GroupOpenResponse.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { [RequestPath("groups.open")] public class GroupOpenResponse : Response diff --git a/SlackAPI/RPCMessages/GroupRenameResponse.cs b/SlackAPI/RPCMessages/GroupRenameResponse.cs index 6590576..6e34419 100644 --- a/SlackAPI/RPCMessages/GroupRenameResponse.cs +++ b/SlackAPI/RPCMessages/GroupRenameResponse.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { [RequestPath("groups.rename")] public class GroupRenameResponse : Response diff --git a/SlackAPI/RPCMessages/GroupResponse.cs b/SlackAPI/RPCMessages/GroupResponse.cs index f8834bc..c17623e 100644 --- a/SlackAPI/RPCMessages/GroupResponse.cs +++ b/SlackAPI/RPCMessages/GroupResponse.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { public class GroupResponse : Response { diff --git a/SlackAPI/RPCMessages/GroupSetPurposeResponse.cs b/SlackAPI/RPCMessages/GroupSetPurposeResponse.cs index 93a061c..306096b 100644 --- a/SlackAPI/RPCMessages/GroupSetPurposeResponse.cs +++ b/SlackAPI/RPCMessages/GroupSetPurposeResponse.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { [RequestPath("groups.setPurpose")] public class GroupSetPurposeResponse : Response diff --git a/SlackAPI/RPCMessages/GroupSetTopicResponse.cs b/SlackAPI/RPCMessages/GroupSetTopicResponse.cs index f8adab9..fcfff18 100644 --- a/SlackAPI/RPCMessages/GroupSetTopicResponse.cs +++ b/SlackAPI/RPCMessages/GroupSetTopicResponse.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { [RequestPath("groups.setTopic")] public class GroupSetTopicResponse : Response diff --git a/SlackAPI/RPCMessages/GroupUnarchiveResponse.cs b/SlackAPI/RPCMessages/GroupUnarchiveResponse.cs index d68061c..639d5ad 100644 --- a/SlackAPI/RPCMessages/GroupUnarchiveResponse.cs +++ b/SlackAPI/RPCMessages/GroupUnarchiveResponse.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { [RequestPath("groups.unarchive")] public class GroupUnarchiveResponse : Response diff --git a/SlackAPI/RPCMessages/LoginResponse.cs b/SlackAPI/RPCMessages/LoginResponse.cs index d048f31..23b9392 100644 --- a/SlackAPI/RPCMessages/LoginResponse.cs +++ b/SlackAPI/RPCMessages/LoginResponse.cs @@ -1,12 +1,8 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace SlackAPI { - [RequestPath("rtm.start")] + [RequestPath("rtm.start")] public class LoginResponse : Response { public Bot[] bots; diff --git a/SlackAPI/RPCMessages/MarkResponse.cs b/SlackAPI/RPCMessages/MarkResponse.cs index 976b0c9..24fbaae 100644 --- a/SlackAPI/RPCMessages/MarkResponse.cs +++ b/SlackAPI/RPCMessages/MarkResponse.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { /// /// This is used for moving the read cursor in the channel. diff --git a/SlackAPI/RPCMessages/MessageHistory.cs b/SlackAPI/RPCMessages/MessageHistory.cs index ba2541c..f0785f2 100644 --- a/SlackAPI/RPCMessages/MessageHistory.cs +++ b/SlackAPI/RPCMessages/MessageHistory.cs @@ -1,5 +1,4 @@ using System; -using Newtonsoft.Json.Serialization; namespace SlackAPI { diff --git a/SlackAPI/RPCMessages/PinListResponse.cs b/SlackAPI/RPCMessages/PinListResponse.cs new file mode 100644 index 0000000..f1cb9d0 --- /dev/null +++ b/SlackAPI/RPCMessages/PinListResponse.cs @@ -0,0 +1,19 @@ +namespace SlackAPI +{ + // https://api.slack.com/methods/pins.list + [RequestPath("pins.list")] + public class PinListResponse : Response + { + public class PinItem + { + public string type; // message, file, file_comment + public Message message; // message + public string channel; // message + public File file; // file, file_comment + public string file_comment; // file_comment + public long created; + } + + public PinItem[] items; + } +} diff --git a/SlackAPI/RPCMessages/PinRemoveResponse.cs b/SlackAPI/RPCMessages/PinRemoveResponse.cs new file mode 100644 index 0000000..9398b03 --- /dev/null +++ b/SlackAPI/RPCMessages/PinRemoveResponse.cs @@ -0,0 +1,8 @@ +namespace SlackAPI +{ + // https://api.slack.com/methods/pins.remove + [RequestPath("pins.remove")] + public class PinRemoveResponse : Response + { + } +} diff --git a/SlackAPI/RPCMessages/PresenseResponse.cs b/SlackAPI/RPCMessages/PresenceResponse.cs similarity index 54% rename from SlackAPI/RPCMessages/PresenseResponse.cs rename to SlackAPI/RPCMessages/PresenceResponse.cs index 5c3c333..09730c6 100644 --- a/SlackAPI/RPCMessages/PresenseResponse.cs +++ b/SlackAPI/RPCMessages/PresenceResponse.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { [RequestPath("users.setPresence")] public class PresenceResponse : Response diff --git a/SlackAPI/RPCMessages/ProfileSetRespose.cs b/SlackAPI/RPCMessages/ProfileSetRespose.cs new file mode 100644 index 0000000..3fa60a9 --- /dev/null +++ b/SlackAPI/RPCMessages/ProfileSetRespose.cs @@ -0,0 +1,8 @@ +namespace SlackAPI +{ + [RequestPath("users.profile.set")] + public class ProfileSetRespose : Response + { + public UserProfile profile; + } +} diff --git a/SlackAPI/RPCMessages/SearchResponseAll.cs b/SlackAPI/RPCMessages/SearchResponseAll.cs index 80d224b..0094ff9 100644 --- a/SlackAPI/RPCMessages/SearchResponseAll.cs +++ b/SlackAPI/RPCMessages/SearchResponseAll.cs @@ -1,6 +1,4 @@ -using System; - -namespace SlackAPI +namespace SlackAPI { [RequestPath("search.all")] public class SearchResponseAll : Response diff --git a/SlackAPI/RPCMessages/SearchResponseFiles.cs b/SlackAPI/RPCMessages/SearchResponseFiles.cs index 9b8b284..fe9551e 100644 --- a/SlackAPI/RPCMessages/SearchResponseFiles.cs +++ b/SlackAPI/RPCMessages/SearchResponseFiles.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { [RequestPath("search.files")] public class SearchResponseFiles : Response diff --git a/SlackAPI/RPCMessages/SearchResponseMessages.cs b/SlackAPI/RPCMessages/SearchResponseMessages.cs index 6131f94..8f60216 100644 --- a/SlackAPI/RPCMessages/SearchResponseMessages.cs +++ b/SlackAPI/RPCMessages/SearchResponseMessages.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { [RequestPath("search.messages")] public class SearchResponseMessages : Response diff --git a/SlackAPI/RPCMessages/StarListResponse.cs b/SlackAPI/RPCMessages/StarListResponse.cs index 2fe3e7d..14cfd37 100644 --- a/SlackAPI/RPCMessages/StarListResponse.cs +++ b/SlackAPI/RPCMessages/StarListResponse.cs @@ -1,6 +1,4 @@ -using System; - -namespace SlackAPI +namespace SlackAPI { [RequestPath("stars.list")] public class StarListResponse : Response diff --git a/SlackAPI/RPCMessages/UserCountsResponse.cs b/SlackAPI/RPCMessages/UserCountsResponse.cs index 2e82026..a4b0cd9 100644 --- a/SlackAPI/RPCMessages/UserCountsResponse.cs +++ b/SlackAPI/RPCMessages/UserCountsResponse.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { [RequestPath("users.counts")] public class UserCountsResponse : Response diff --git a/SlackAPI/RPCMessages/UserListResponse.cs b/SlackAPI/RPCMessages/UserListResponse.cs index 4e2a3ec..50ad988 100644 --- a/SlackAPI/RPCMessages/UserListResponse.cs +++ b/SlackAPI/RPCMessages/UserListResponse.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { [RequestPath("users.list")] public class UserListResponse : Response diff --git a/SlackAPI/RPCMessages/UserPreferencesResponse.cs b/SlackAPI/RPCMessages/UserPreferencesResponse.cs index f8f69c0..1648917 100644 --- a/SlackAPI/RPCMessages/UserPreferencesResponse.cs +++ b/SlackAPI/RPCMessages/UserPreferencesResponse.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { [RequestPath("users.prefs.get")] public class UserPreferencesResponse: Response diff --git a/SlackAPI/ReactionAddedResponse.cs b/SlackAPI/ReactionAddedResponse.cs index b641ac3..92beccb 100644 --- a/SlackAPI/ReactionAddedResponse.cs +++ b/SlackAPI/ReactionAddedResponse.cs @@ -1,14 +1,7 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { [RequestPath("reactions.add")] public class ReactionAddedResponse : Response { - } } diff --git a/SlackAPI/Request.cs b/SlackAPI/Request.cs index 2af5854..66bc198 100644 --- a/SlackAPI/Request.cs +++ b/SlackAPI/Request.cs @@ -1,11 +1,8 @@ -using Newtonsoft.Json; -using System; +using System; using System.Collections.Generic; using System.IO; using System.Net; using System.Reflection; -using System.Text; -using System.Threading; namespace SlackAPI { @@ -48,16 +45,16 @@ public void GotRequest(IAsyncResult result) if (result.AsyncState != this) throw new InvalidOperationException("This shouldn't be happening! D:"); - using (Stream requestStream = request.EndGetRequestStream(result)) + using (var requestStream = request.EndGetRequestStream(result)) if (Post.Length > 0) - using (StreamWriter writer = new StreamWriter(requestStream)) + using (var writer = new StreamWriter(requestStream)) { bool first = true; foreach (Tuple postEntry in Post) { if (!first) writer.Write(','); - + writer.Write(string.Format("{0}={1}", Uri.EscapeDataString(postEntry.Item1), Uri.EscapeDataString(postEntry.Item2))); first = false; @@ -129,7 +126,7 @@ private K CreateDefaultResponseForError(Exception e) } } - [AttributeUsage(AttributeTargets.Class, Inherited=false)] + [AttributeUsage(AttributeTargets.Class, Inherited = false)] public class RequestPath : Attribute { //See notes in Slack:APIRequest @@ -145,13 +142,13 @@ public RequestPath(string requestPath, bool isPrimaryAPI = true) public static RequestPath GetRequestPath() { - Type t = typeof(K); + var t = typeof(K); if (paths.ContainsKey(t)) return paths[t]; - TypeInfo info = t.GetTypeInfo(); + var info = t.GetTypeInfo(); - RequestPath path = info.GetCustomAttribute(); + var path = info.GetCustomAttribute(); if (path == null) throw new InvalidOperationException(string.Format("No valid request path for {0}", t.Name)); paths.Add(t, path); diff --git a/SlackAPI/RequestStateForTask.cs b/SlackAPI/RequestStateForTask.cs index 63075b7..735f625 100644 --- a/SlackAPI/RequestStateForTask.cs +++ b/SlackAPI/RequestStateForTask.cs @@ -1,10 +1,6 @@ -using Newtonsoft.Json; -using System; -using System.Collections.Generic; +using System; using System.IO; -using System.Linq; using System.Net; -using System.Text; using System.Threading.Tasks; namespace SlackAPI @@ -52,9 +48,9 @@ private async Task ExecuteResult() K responseObj; - using (Stream responseReading = response.GetResponseStream()) + using (var responseReading = response.GetResponseStream()) { - using (StreamReader reader = new StreamReader(responseReading)) + using (var reader = new StreamReader(responseReading)) { string responseData = reader.ReadToEnd(); responseObj = responseData.Deserialize(); @@ -68,14 +64,14 @@ private async Task ExecutePost() { request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; - using (Stream requestStream = await request.GetRequestStreamAsync()) + using (var requestStream = await request.GetRequestStreamAsync()) { if (Post.Length > 0) { - using (StreamWriter writer = new StreamWriter(requestStream)) + using (var writer = new StreamWriter(requestStream)) { - bool first = true; - foreach (Tuple postEntry in Post) + var first = true; + foreach (var postEntry in Post) { if (!first) writer.Write('&'); diff --git a/SlackAPI/Response.cs b/SlackAPI/Response.cs index 6c60a0d..0c9e355 100644 --- a/SlackAPI/Response.cs +++ b/SlackAPI/Response.cs @@ -1,8 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace SlackAPI { diff --git a/SlackAPI/SlackAPI.csproj b/SlackAPI/SlackAPI.csproj index c2ccdea..bf8eff9 100644 --- a/SlackAPI/SlackAPI.csproj +++ b/SlackAPI/SlackAPI.csproj @@ -63,6 +63,18 @@ + + + + + + + + + + + + @@ -102,7 +114,7 @@ - + @@ -161,6 +173,7 @@ + diff --git a/SlackAPI/SlackClient.cs b/SlackAPI/SlackClient.cs index c38eba1..6bc3e8c 100644 --- a/SlackAPI/SlackClient.cs +++ b/SlackAPI/SlackClient.cs @@ -1,4 +1,5 @@ using Newtonsoft.Json; +using SlackAPI.RPCMessages; using System; using System.Collections.Generic; using System.IO; @@ -7,7 +8,6 @@ using System.Net.Http; using System.Text; using System.Threading; -using SlackAPI.RPCMessages; namespace SlackAPI { @@ -19,7 +19,8 @@ namespace SlackAPI public class SlackClient { readonly string APIToken; - bool authWorks = false; + readonly Tuple[] APILoginParameters; + //bool authWorks = false; const string APIBaseLocation = "https://slack.com/api/"; const int Timeout = 5000; @@ -57,17 +58,20 @@ public class SlackClient //public event Action OnPresenceChanged; //public event Action OnHello; - public SlackClient(string token) + public SlackClient(string token, Tuple[] loginParameters = null) { APIToken = token; + APILoginParameters = loginParameters; } - public virtual void Connect(Action onConnected = null, Action onSocketConnected = null) + public virtual void Connect(Action onConnected = null, Action onSocketConnected = null) { EmitLogin((loginDetails) => { - if(loginDetails.ok) - Connected(loginDetails); + if (loginDetails.ok) + Connected(loginDetails); + else + throw new InvalidOperationException(loginDetails.error); if (onConnected != null) onConnected(loginDetails); }); @@ -92,25 +96,25 @@ protected virtual void Connected(LoginResponse loginDetails) ).ToList(); UserLookup = new Dictionary(); - foreach (User u in Users) UserLookup.Add(u.id, u); + foreach (var u in Users) UserLookup.Add(u.id, u); ChannelLookup = new Dictionary(); ConversationLookup = new Dictionary(); - foreach (Channel c in Channels) + foreach (var c in Channels) { ChannelLookup.Add(c.id, c); ConversationLookup.Add(c.id, c); } GroupLookup = new Dictionary(); - foreach (Channel g in Groups) + foreach (var g in Groups) { GroupLookup.Add(g.id, g); ConversationLookup.Add(g.id, g); } DirectMessageLookup = new Dictionary(); - foreach (DirectMessageConversation im in DirectMessages) + foreach (var im in DirectMessages) { DirectMessageLookup.Add(im.id, im); ConversationLookup.Add(im.id, im); @@ -119,43 +123,30 @@ protected virtual void Connected(LoginResponse loginDetails) internal static Uri GetSlackUri(string path, Tuple[] getParameters) { - string parameters = getParameters + var parameters = getParameters .Where(x => x.Item2 != null) - .Select(new Func, string>(a => - { - try - { - return string.Format("{0}={1}", Uri.EscapeDataString(a.Item1), Uri.EscapeDataString(a.Item2)); - } - catch (Exception ex) - { - throw new InvalidOperationException(string.Format("Failed when processing '{0}'.", a), ex); - } - })) - .Aggregate((a, b) => + .Select(new Func, string>(a => { - if (string.IsNullOrEmpty(a)) - return b; - else - return string.Format("{0}&{1}", a, b); - }); - - Uri requestUri = new Uri(string.Format("{0}?{1}", path, parameters)); + try { return string.Format("{0}={1}", Uri.EscapeDataString(a.Item1), Uri.EscapeDataString(a.Item2)); } + catch (Exception ex) { throw new InvalidOperationException(string.Format("Failed when processing '{0}'.", a), ex); } + })) + .Aggregate((a, b) => (string.IsNullOrEmpty(a) ? b : string.Format("{0}&{1}", a, b))); + var requestUri = new Uri(string.Format("{0}?{1}", path, parameters)); return requestUri; } public static void APIRequest(Action callback, Tuple[] getParameters, Tuple[] postParameters) where K : Response { - RequestPath path = RequestPath.GetRequestPath(); + var path = RequestPath.GetRequestPath(); //TODO: Custom paths? Appropriate subdomain paths? Not sure. //Maybe store custom path in the requestpath.path itself? - Uri requestUri = GetSlackUri(Path.Combine(APIBaseLocation, path.Path), getParameters); - HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(requestUri); + var requestUri = GetSlackUri(Path.Combine(APIBaseLocation, path.Path), getParameters); + var request = (HttpWebRequest)HttpWebRequest.Create(requestUri); //This will handle all of the processing. - RequestState state = new RequestState(request, postParameters, callback); + var state = new RequestState(request, postParameters, callback); state.Begin(); } @@ -165,10 +156,10 @@ public static void APIGetRequest(Action callback, params Tuple(callback, getParameters, new Tuple[0]); } - public void APIRequestWithToken(Action callback, params Tuple[] getParameters) + public void APIRequestWithToken(Action callback, params Tuple[] getParameters) where K : Response { - Tuple[] tokenArray = new Tuple[]{ + var tokenArray = new Tuple[]{ new Tuple("token", APIToken) }; @@ -188,13 +179,13 @@ public static void FindTeam(Action callback, string team) { //This seems to accept both 'team.slack.com' and just plain 'team'. //Going to go with the latter. - Tuple domainName = new Tuple("domain", team); + var domainName = new Tuple("domain", team); APIRequest(callback, new Tuple[] { domainName }, new Tuple[0]); } public static void AuthSignin(Action callback, string userId, string teamId, string password) { - APIRequest(callback, new Tuple[] { + APIRequest(callback, new Tuple[] { new Tuple("user", userId), new Tuple("team", teamId), new Tuple("password", password) @@ -210,10 +201,11 @@ public void GetUserList(Action callback) { APIRequestWithToken(callback); } - public void ChannelsCreate(Action callback, string name) { - APIRequestWithToken(callback, new Tuple("name", name)); - } - public void GetChannelList(Action callback, bool ExcludeArchived = true) + public void ChannelsCreate(Action callback, string name) + { + APIRequestWithToken(callback, new Tuple("name", name)); + } + public void GetChannelList(Action callback, bool ExcludeArchived = true) { APIRequestWithToken(callback, new Tuple("exclude_archived", ExcludeArchived ? "1" : "0")); } @@ -230,10 +222,10 @@ public void GetDirectMessageList(Action c public void GetFiles(Action callback, string userId = null, DateTime? from = null, DateTime? to = null, int? count = null, int? page = null, FileTypes types = FileTypes.all) { - List> parameters = new List>(); + var parameters = new List>(); if (!string.IsNullOrEmpty(userId)) - parameters.Add(new Tuple("user", userId)); + parameters.Add(new Tuple("user", userId)); if (from.HasValue) parameters.Add(new Tuple("ts_from", from.Value.ToProperTimeStamp())); @@ -243,11 +235,11 @@ public void GetFiles(Action callback, string userId = null, Da if (!types.HasFlag(FileTypes.all)) { - FileTypes[] values = (FileTypes[])Enum.GetValues(typeof(FileTypes)); - - StringBuilder building = new StringBuilder(); - bool first = true; - for (int i = 0; i < values.Length; ++i) + var values = (FileTypes[])Enum.GetValues(typeof(FileTypes)); + + var building = new StringBuilder(); + var first = true; + for (var i = 0; i < values.Length; ++i) { if (types.HasFlag(values[i])) { @@ -275,15 +267,15 @@ public void GetFiles(Action callback, string userId = null, Da void GetHistory(Action historyCallback, string channel, DateTime? latest = null, DateTime? oldest = null, int? count = null) where K : MessageHistory { - List> parameters = new List>(); + var parameters = new List>(); parameters.Add(new Tuple("channel", channel)); - - if(latest.HasValue) + + if (latest.HasValue) parameters.Add(new Tuple("latest", latest.Value.ToProperTimeStamp())); - if(oldest.HasValue) + if (oldest.HasValue) parameters.Add(new Tuple("oldest", oldest.Value.ToProperTimeStamp())); - if(count.HasValue) - parameters.Add(new Tuple("count", count.Value.ToString())); + if (count.HasValue) + parameters.Add(new Tuple("count", count.Value.ToString())); APIRequestWithToken(historyCallback, parameters.ToArray()); } @@ -313,18 +305,19 @@ public void MarkChannel(Action callback, string channelId, DateTim public void GetFileInfo(Action callback, string fileId, int? page = null, int? count = null) { - List> parameters = new List>(); + var parameters = new List>(); - parameters.Add(new Tuple("file", fileId)); - - if(count.HasValue) - parameters.Add(new Tuple("count", count.Value.ToString())); + parameters.Add(new Tuple("file", fileId)); + + if (count.HasValue) + parameters.Add(new Tuple("count", count.Value.ToString())); if (page.HasValue) parameters.Add(new Tuple("page", page.Value.ToString())); APIRequestWithToken(callback, parameters.ToArray()); } + #region Groups public void GroupsArchive(Action callback, string channelId) { @@ -348,7 +341,7 @@ public void GroupsCreateChild(Action callback, string public void GroupsInvite(Action callback, string userId, string channelId) { - List> parameters = new List>(); + var parameters = new List>(); parameters.Add(new Tuple("channel", channelId)); parameters.Add(new Tuple("user", userId)); @@ -358,7 +351,7 @@ public void GroupsInvite(Action callback, string userId, st public void GroupsKick(Action callback, string userId, string channelId) { - List> parameters = new List>(); + var parameters = new List>(); parameters.Add(new Tuple("channel", channelId)); parameters.Add(new Tuple("user", userId)); @@ -383,7 +376,7 @@ public void GroupsOpen(Action callback, string channelId) public void GroupsRename(Action callback, string channelId, string name) { - List> parameters = new List>(); + var parameters = new List>(); parameters.Add(new Tuple("channel", channelId)); parameters.Add(new Tuple("name", name)); @@ -393,7 +386,7 @@ public void GroupsRename(Action callback, string channelId, public void GroupsSetPurpose(Action callback, string channelId, string purpose) { - List> parameters = new List>(); + var parameters = new List>(); parameters.Add(new Tuple("channel", channelId)); parameters.Add(new Tuple("purpose", purpose)); @@ -403,7 +396,7 @@ public void GroupsSetPurpose(Action callback, string ch public void GroupsSetTopic(Action callback, string channelId, string topic) { - List> parameters = new List>(); + var parameters = new List>(); parameters.Add(new Tuple("channel", channelId)); parameters.Add(new Tuple("topic", topic)); @@ -420,7 +413,7 @@ public void GroupsUnarchive(Action callback, string chan public void SearchAll(Action callback, string query, SearchSort? sorting = null, SearchSortDirection? direction = null, bool enableHighlights = false, int? count = null, int? page = null) { - List> parameters = new List>(); + var parameters = new List>(); parameters.Add(new Tuple("query", query)); if (sorting.HasValue) @@ -443,7 +436,7 @@ public void SearchAll(Action callback, string query, SearchSo public void SearchMessages(Action callback, string query, SearchSort? sorting = null, SearchSortDirection? direction = null, bool enableHighlights = false, int? count = null, int? page = null) { - List> parameters = new List>(); + var parameters = new List>(); parameters.Add(new Tuple("query", query)); if (sorting.HasValue) @@ -466,7 +459,7 @@ public void SearchMessages(Action callback, string query public void SearchFiles(Action callback, string query, SearchSort? sorting = null, SearchSortDirection? direction = null, bool enableHighlights = false, int? count = null, int? page = null) { - List> parameters = new List>(); + var parameters = new List>(); parameters.Add(new Tuple("query", query)); if (sorting.HasValue) @@ -487,24 +480,25 @@ public void SearchFiles(Action callback, string query, Sear APIRequestWithToken(callback, parameters.ToArray()); } - public void GetStars(Action callback, string userId = null, int? count = null, int? page = null){ - List> parameters = new List>(); - - if(!string.IsNullOrEmpty(userId)) - parameters.Add(new Tuple("user", userId)); + public void GetStars(Action callback, string userId = null, int? count = null, int? page = null) + { + var parameters = new List>(); + + if (!string.IsNullOrEmpty(userId)) + parameters.Add(new Tuple("user", userId)); - if(count.HasValue) - parameters.Add(new Tuple("count", count.Value.ToString())); + if (count.HasValue) + parameters.Add(new Tuple("count", count.Value.ToString())); - if(page.HasValue) - parameters.Add(new Tuple("page", page.Value.ToString())); + if (page.HasValue) + parameters.Add(new Tuple("page", page.Value.ToString())); APIRequestWithToken(callback, parameters.ToArray()); } public void DeleteMessage(Action callback, string channelId, DateTime ts) { - List> parameters = new List>() + var parameters = new List>() { new Tuple("ts", ts.ToProperTimeStamp()), new Tuple("channel", channelId) @@ -544,7 +538,14 @@ public void GetInfo(Action callback, string user) public void EmitLogin(Action callback, string agent = "Inumedia.SlackAPI") { - APIRequestWithToken(callback, new Tuple("agent", agent)); + var parameterArray = new Tuple[]{ + new Tuple("agent", agent) + }; + + if (APILoginParameters != null && APILoginParameters.Length > 0) + parameterArray = parameterArray.Concat(APILoginParameters).ToArray(); + + APIRequestWithToken(callback, parameterArray); } public void Update( @@ -558,7 +559,7 @@ public void Update( Attachment[] attachments = null, bool as_user = false) { - List> parameters = new List>(); + var parameters = new List>(); parameters.Add(new Tuple("ts", ts)); parameters.Add(new Tuple("channel", channelId)); @@ -599,15 +600,15 @@ public void PostMessage( string icon_url = null, string icon_emoji = null, bool as_user = false, - string thread_ts = null) + string thread_ts = null) { - List> parameters = new List>(); + var parameters = new List>(); - parameters.Add(new Tuple("channel", channelId)); - parameters.Add(new Tuple("text", text)); + parameters.Add(new Tuple("channel", channelId)); + parameters.Add(new Tuple("text", text)); - if(!string.IsNullOrEmpty(botName)) - parameters.Add(new Tuple("username", botName)); + if (!string.IsNullOrEmpty(botName)) + parameters.Add(new Tuple("username", botName)); if (!string.IsNullOrEmpty(parse)) parameters.Add(new Tuple("parse", parse)); @@ -633,7 +634,7 @@ public void PostMessage( parameters.Add(new Tuple("icon_emoji", icon_emoji)); parameters.Add(new Tuple("as_user", as_user.ToString())); - + if (!string.IsNullOrEmpty(thread_ts)) parameters.Add(new Tuple("thread_ts", thread_ts)); @@ -647,7 +648,7 @@ public void AddReaction( string channel = null, string timestamp = null) { - List> parameters = new List>(); + var parameters = new List>(); if (!string.IsNullOrEmpty(name)) parameters.Add(new Tuple("name", name)); @@ -663,9 +664,9 @@ public void AddReaction( public void UploadFile(Action callback, byte[] fileData, string fileName, string[] channelIds, string title = null, string initialComment = null, bool useAsync = false, string fileType = null) { - Uri target = new Uri(Path.Combine(APIBaseLocation, useAsync ? "files.uploadAsync" : "files.upload")); + var target = new Uri(Path.Combine(APIBaseLocation, useAsync ? "files.uploadAsync" : "files.upload")); - List parameters = new List(); + var parameters = new List(); parameters.Add(string.Format("token={0}", APIToken)); //File/Content @@ -683,12 +684,12 @@ public void UploadFile(Action callback, byte[] fileData, str parameters.Add(string.Format("{0}={1}", "channels", string.Join(",", channelIds))); - using(HttpClient client = new HttpClient()) - using (MultipartFormDataContent form = new MultipartFormDataContent()) + using (var client = new HttpClient()) + using (var form = new MultipartFormDataContent()) { form.Add(new ByteArrayContent(fileData), "file", fileName); - HttpResponseMessage response = client.PostAsync(string.Format("{0}?{1}", target, string.Join("&", parameters.ToArray())), form).Result; - string result = response.Content.ReadAsStringAsync().Result; + var response = client.PostAsync(string.Format("{0}?{1}", target, string.Join("&", parameters.ToArray())), form).Result; + var result = response.Content.ReadAsStringAsync().Result; callback(result.Deserialize()); } } @@ -696,29 +697,29 @@ public void UploadFile(Action callback, byte[] fileData, str private static string BuildScope(SlackScope scope) { var builder = new StringBuilder(); - if ((int)(scope & SlackScope.Identify) != 0) + if ((scope & SlackScope.Identify) != 0) builder.Append("identify"); - if ((int)(scope & SlackScope.Read) != 0) + if ((scope & SlackScope.Read) != 0) { - if(builder.Length > 0) + if (builder.Length > 0) builder.Append(","); builder.Append("read"); } - if ((int)(scope & SlackScope.Post) != 0) + if ((scope & SlackScope.Post) != 0) { - if(builder.Length > 0) + if (builder.Length > 0) builder.Append(","); builder.Append("post"); } - if ((int)(scope & SlackScope.Client) != 0) + if ((scope & SlackScope.Client) != 0) { - if(builder.Length > 0) + if (builder.Length > 0) builder.Append(","); builder.Append("client"); } - if ((int)(scope & SlackScope.Admin) != 0) + if ((scope & SlackScope.Admin) != 0) { - if(builder.Length > 0) + if (builder.Length > 0) builder.Append(","); builder.Append("admin"); } @@ -728,12 +729,12 @@ private static string BuildScope(SlackScope scope) public static Uri GetAuthorizeUri(string clientId, SlackScope scopes, string redirectUri = null, string state = null, string team = null) { - string theScopes = BuildScope(scopes); + var theScopes = BuildScope(scopes); return GetSlackUri("https://slack.com/oauth/authorize", new Tuple[] { new Tuple("client_id", clientId), new Tuple("redirect_uri", redirectUri), - new Tuple("state", state), - new Tuple("scope", theScopes), + new Tuple("state", state), + new Tuple("scope", theScopes), new Tuple("team", team)}); } @@ -741,7 +742,7 @@ public static void GetAccessToken(Action callback, string c { APIRequest(callback, new Tuple[] { new Tuple("client_id", clientId), new Tuple("client_secret", clientSecret), new Tuple("code", code), - new Tuple("redirect_uri", redirectUri) }, new Tuple[] {}); + new Tuple("redirect_uri", redirectUri) }, new Tuple[] { }); } public static void RegisterConverter(JsonConverter converter) diff --git a/SlackAPI/SlackScope.cs b/SlackAPI/SlackScope.cs index 3819c05..f110e62 100644 --- a/SlackAPI/SlackScope.cs +++ b/SlackAPI/SlackScope.cs @@ -1,8 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace SlackAPI { diff --git a/SlackAPI/SlackSocket.cs b/SlackAPI/SlackSocket.cs index dc541eb..5936573 100644 --- a/SlackAPI/SlackSocket.cs +++ b/SlackAPI/SlackSocket.cs @@ -1,14 +1,14 @@ -using System.IO; -using Newtonsoft.Json; +using Newtonsoft.Json; using SlackAPI.Utilities; using System; using System.Collections.Generic; +using System.IO; +using System.Linq; using System.Net.WebSockets; using System.Reflection; using System.Text; using System.Threading; using System.Threading.Tasks; -using System.Linq; #if NETSTANDARD1_6 using Microsoft.Extensions.DependencyModel; @@ -42,7 +42,7 @@ static SlackSocket() { routing = new Dictionary>(); #if NET45 - var assemblies = AppDomain.CurrentDomain.GetAssemblies().Where(x => x.GlobalAssemblyCache == false); + var assemblies = AppDomain.CurrentDomain.GetAssemblies().Where(x => x.GlobalAssemblyCache == false); #elif NETSTANDARD1_6 var assemblies = DependencyContext.Default.GetDefaultAssemblyNames().Select(Assembly.Load); #elif NETSTANDARD1_3 @@ -51,7 +51,7 @@ static SlackSocket() #else #error Platform not supported #endif - foreach (Assembly assembly in assemblies) + foreach (var assembly in assemblies) { Type[] assemblyTypes; try @@ -63,9 +63,9 @@ static SlackSocket() return; } - foreach (Type type in assemblyTypes) + foreach (var type in assemblyTypes) { - foreach (SlackSocketRouting route in type.GetTypeInfo().GetCustomAttributes()) + foreach (var route in type.GetTypeInfo().GetCustomAttributes()) { if (!routing.ContainsKey(route.Type)) { @@ -90,7 +90,7 @@ static SlackSocket() } } - public SlackSocket(LoginResponse loginDetails, object routingTo, Action onConnected = null) + public SlackSocket(LoginResponse loginDetails, object routingTo, Action onConnected = null) { BuildRoutes(routingTo); socket = new ClientWebSocket(); @@ -100,7 +100,7 @@ public SlackSocket(LoginResponse loginDetails, object routingTo, Action onConnec cts = new CancellationTokenSource(); socket.ConnectAsync(new Uri(string.Format("{0}?svn_rev={1}&login_with_boot_data-0-{2}&on_login-0-{2}&connect-1-{2}", loginDetails.url, loginDetails.svn_rev, DateTime.Now.Subtract(new DateTime(1970, 1, 1)).TotalSeconds)), cts.Token).Wait(); - if(onConnected != null) + if (onConnected != null) onConnected(); SetupReceiving(); } @@ -109,19 +109,19 @@ void BuildRoutes(object routingTo) { routes = new Dictionary>(); - Type routingToType = routingTo.GetType(); - Type slackMessage = typeof(SlackSocketMessage); - foreach (MethodInfo m in routingTo.GetType().GetMethods(BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.NonPublic | BindingFlags.Public)) + var routingToType = routingTo.GetType(); + var slackMessage = typeof(SlackSocketMessage); + foreach (var m in routingTo.GetType().GetMethods(BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.NonPublic | BindingFlags.Public)) { - ParameterInfo[] parameters = m.GetParameters(); + var parameters = m.GetParameters(); if (parameters.Length != 1) continue; if (parameters[0].ParameterType.GetTypeInfo().IsSubclassOf(slackMessage)) { - Type t = parameters[0].ParameterType; - foreach (SlackSocketRouting route in t.GetTypeInfo().GetCustomAttributes()) + var t = parameters[0].ParameterType; + foreach (var route in t.GetTypeInfo().GetCustomAttributes()) { - Type genericAction = typeof(Action<>).MakeGenericType(parameters[0].ParameterType); - Delegate d = m.CreateDelegate(genericAction, routingTo); + var genericAction = typeof(Action<>).MakeGenericType(parameters[0].ParameterType); + var d = m.CreateDelegate(genericAction, routingTo); if (d == null) { System.Diagnostics.Debug.WriteLine(string.Format("Couldn't create delegate for {0}.{1}", routingToType.FullName, m.Name)); @@ -141,11 +141,11 @@ void BuildRoutes(object routingTo) public void Send(SlackSocketMessage message, Action callback) where K : SlackSocketMessage { - int sendingId = Interlocked.Increment(ref currentId); + var sendingId = Interlocked.Increment(ref currentId); message.id = sendingId; callbacks.Add(sendingId, (c) => { - K obj = c.Deserialize(); + var obj = c.Deserialize(); callback(obj); }); Send(message); @@ -157,11 +157,12 @@ public void Send(SlackSocketMessage message) message.id = Interlocked.Increment(ref currentId); //socket.Send(JsonConvert.SerializeObject(message)); - if (string.IsNullOrEmpty(message.type)){ - IEnumerable routes = message.GetType().GetTypeInfo().GetCustomAttributes(); + if (string.IsNullOrEmpty(message.type)) + { + var routes = message.GetType().GetTypeInfo().GetCustomAttributes(); SlackSocketRouting route = null; - foreach (SlackSocketRouting r in routes) + foreach (var r in routes) { route = r; } @@ -173,16 +174,15 @@ public void Send(SlackSocketMessage message) } } - sendingQueue.Push(JsonConvert.SerializeObject(message, Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore })); + sendingQueue.Push(JsonConvert.SerializeObject(message, Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore })); if (Interlocked.CompareExchange(ref currentlySending, 1, 0) == 0) Task.Factory.StartNew(HandleSending); } public void BindCallback(Action callback) { - Type t = typeof(K); - - foreach (SlackSocketRouting route in t.GetTypeInfo().GetCustomAttributes()) + var t = typeof(K); + foreach (var route in t.GetTypeInfo().GetCustomAttributes()) { if (!routes.ContainsKey(route.Type)) routes.Add(route.Type, new Dictionary()); @@ -195,13 +195,13 @@ public void BindCallback(Action callback) public void UnbindCallback(Action callback) { - Type t = typeof(K); - foreach (SlackSocketRouting route in t.GetTypeInfo().GetCustomAttributes()) + var t = typeof(K); + foreach (var route in t.GetTypeInfo().GetCustomAttributes()) { - Delegate d = routes.ContainsKey(route.Type) ? (routes.ContainsKey(route.SubType ?? "null") ? routes[route.Type][route.SubType ?? "null"] : null) : null; + var d = routes.ContainsKey(route.Type) ? (routes.ContainsKey(route.SubType ?? "null") ? routes[route.Type][route.SubType ?? "null"] : null) : null; if (d != null) { - Delegate newd = Delegate.Remove(d, callback); + var newd = Delegate.Remove(d, callback); routes[route.Type][route.SubType ?? "null"] = newd; } } @@ -212,10 +212,10 @@ void SetupReceiving() Task.Factory.StartNew( async () => { - List buffers = new List(); - byte[] bytes = new byte[1024]; + var buffers = new List(); + var bytes = new byte[1024]; buffers.Add(bytes); - ArraySegment buffer = new ArraySegment(bytes); + var buffer = new ArraySegment(bytes); while (socket.State == WebSocketState.Open) { WebSocketReceiveResult result = null; @@ -239,7 +239,7 @@ void SetupReceiving() continue; } - string data = string.Join("", buffers.Select((c) => Encoding.UTF8.GetString(c).TrimEnd('\0'))); + var data = string.Join("", buffers.Select((c) => Encoding.UTF8.GetString(c).TrimEnd('\0'))); //Console.WriteLine("SlackSocket data = " + data); SlackSocketMessage message = null; try @@ -282,7 +282,7 @@ void HandleMessage(SlackSocketMessage message, string data) else { //I believe this method is slower than the former. If I'm wrong we can just use this instead. :D - Type t = routes[message.type][message.subtype ?? "null"].GetMethodInfo().GetParameters()[0].ParameterType; + var t = routes[message.type][message.subtype ?? "null"].GetMethodInfo().GetParameters()[0].ParameterType; o = data.Deserialize(t); } routes[message.type][message.subtype ?? "null"].DynamicInvoke(o); @@ -307,8 +307,8 @@ void HandleSending() string message; while (sendingQueue.Pop(out message) && socket.State == WebSocketState.Open && !cts.Token.IsCancellationRequested) { - byte[] sending = Encoding.UTF8.GetBytes(message); - ArraySegment buffer = new ArraySegment(sending); + var sending = Encoding.UTF8.GetBytes(message); + var buffer = new ArraySegment(sending); try { socket.SendAsync(buffer, WebSocketMessageType.Text, true, cts.Token).Wait(); @@ -325,20 +325,19 @@ void HandleSending() currentlySending = 0; } - public void Close() - { + public void Close() + { try { this.socket.Abort(); } catch (Exception ex) { - } if (Interlocked.CompareExchange(ref closedEmitted, 1, 0) == 0 && ConnectionClosed != null) ConnectionClosed(); - } + } } public class SlackSocketMessage diff --git a/SlackAPI/SlackSocketClient.cs b/SlackAPI/SlackSocketClient.cs index 53b708a..1c236d4 100644 --- a/SlackAPI/SlackSocketClient.cs +++ b/SlackAPI/SlackSocketClient.cs @@ -1,8 +1,6 @@ -using System.Net.WebSockets; +using SlackAPI.WebSocketMessages; using System; -using System.Diagnostics; -using System.Threading; -using SlackAPI.WebSocketMessages; +using System.Net.WebSockets; namespace SlackAPI { @@ -13,42 +11,45 @@ public class SlackSocketClient : SlackClient public event Action OnMessageReceived; public event Action OnReactionAdded; public event Action OnPongReceived; + public event Action OnPresenceChangeReceived; + public event Action OnUserChangeReceived; bool HelloReceived; public const int PingInterval = 3000; - int pinging; - Timer pingingThread; + //int pinging; + //Timer pingingThread; public long PingRoundTripMilliseconds { get; private set; } public bool IsReady { get { return HelloReceived; } } public bool IsConnected { get { return underlyingSocket != null && underlyingSocket.Connected; } } public event Action OnHello; - internal LoginResponse loginDetails; + internal LoginResponse loginDetails; - public SlackSocketClient(string token) - : base(token) + public SlackSocketClient(string token, Tuple[] loginParameters = null) + : base(token, loginParameters) { - } - public override void Connect(Action onConnected, Action onSocketConnected = null) - { - base.Connect((s) => { - ConnectSocket(onSocketConnected); - onConnected(s); - }); - } + public override void Connect(Action onConnected, Action onSocketConnected = null) + { + base.Connect((s) => + { + ConnectSocket(onSocketConnected); + onConnected(s); + }); + } protected override void Connected(LoginResponse loginDetails) - { - this.loginDetails = loginDetails; - base.Connected(loginDetails); - } + { + this.loginDetails = loginDetails; + base.Connected(loginDetails); + } - public void ConnectSocket(Action onSocketConnected){ - underlyingSocket = new SlackSocket(loginDetails, this, onSocketConnected); - } + public void ConnectSocket(Action onSocketConnected) + { + underlyingSocket = new SlackSocket(loginDetails, this, onSocketConnected); + } public void ErrorReceiving(Action callback) { @@ -80,6 +81,11 @@ public void SendPresence(Presence status) underlyingSocket.Send(new PresenceChange() { presence = Presence.active, user = base.MySelf.id }); } + public void SendPresenceSub(string[] ids) + { + underlyingSocket.Send(new PresenceSub() { ids = ids }); + } + public void SendTyping(string channelId) { underlyingSocket.Send(new Typing() { channel = channelId }); @@ -92,9 +98,12 @@ public void SendMessage(Action onSent, string channelId, string userName = MySelf.id; } - if (onSent != null) { - underlyingSocket.Send( new Message() {channel = channelId, text = textData, user = userName, type = "message"}, onSent); - } else { + if (onSent != null) + { + underlyingSocket.Send(new Message() { channel = channelId, text = textData, user = userName, type = "message" }, onSent); + } + else + { underlyingSocket.Send(new Message() { channel = channelId, text = textData, user = userName, type = "message" }); } } @@ -113,7 +122,7 @@ public void HandlePongReceived(Pong pong) public void HandleReactionAdded(ReactionAdded reactionAdded) { if (OnReactionAdded != null) - OnReactionAdded(reactionAdded); + OnReactionAdded(reactionAdded); } public void HandleHello(Hello hello) @@ -127,11 +136,15 @@ public void HandleHello(Hello hello) public void HandlePresence(PresenceChange change) { UserLookup[change.user].presence = change.presence.ToString().ToLower(); + if (OnPresenceChangeReceived != null) + OnPresenceChangeReceived(UserLookup[change.user]); } public void HandleUserChange(UserChange change) { UserLookup[change.user.id] = change.user; + if (OnUserChangeReceived != null) + OnUserChangeReceived(UserLookup[change.user.id]); } public void HandleTeamJoin(TeamJoin newuser) @@ -200,36 +213,29 @@ public void HandleGroupRename(GroupRename rename) GroupLookup[rename.channel.id].created = rename.channel.created; } - public void UserTyping(Typing t) + public void HandleUserTyping(Typing t) { - } - public void Message(NewMessage m) + public void HandleMessage(NewMessage m) { if (OnMessageReceived != null) OnMessageReceived(m); } - public void FileShareMessage(FileShareMessage m) + public void HandleFileShareMessage(FileShareMessage m) { if (OnMessageReceived != null) OnMessageReceived(m); } - public void PresenceChange(PresenceChange p) + public void HandleChannelMarked(ChannelMarked m) { - } - public void ChannelMarked(ChannelMarked m) + public void CloseSocket() { - + underlyingSocket.Close(); } - - public void CloseSocket() - { - underlyingSocket.Close(); - } } } diff --git a/SlackAPI/SlackTaskClient.cs b/SlackAPI/SlackTaskClient.cs index be50ad4..f7ae390 100644 --- a/SlackAPI/SlackTaskClient.cs +++ b/SlackAPI/SlackTaskClient.cs @@ -6,7 +6,6 @@ using System.Net; using System.Net.Http; using System.Text; -using System.Threading; using System.Threading.Tasks; namespace SlackAPI @@ -14,7 +13,8 @@ namespace SlackAPI public class SlackTaskClient { readonly string APIToken; - bool authWorks = false; + readonly Tuple[] APILoginParameters; + //bool authWorks = false; const string APIBaseLocation = "https://slack.com/api/"; const int Timeout = 5000; @@ -51,16 +51,17 @@ public class SlackTaskClient //public event Action OnPresenceChanged; //public event Action OnHello; - public SlackTaskClient(string token) + public SlackTaskClient(string token, Tuple[] loginParameters = null) { APIToken = token; + APILoginParameters = loginParameters; } - public virtual async Task ConnectAsync() + public virtual async Task ConnectAsync() { var loginDetails = await EmitLoginAsync(); - if(loginDetails.ok) - Connected(loginDetails); + if (loginDetails.ok) + Connected(loginDetails); return loginDetails; } @@ -99,12 +100,12 @@ protected virtual void Connected(LoginResponse loginDetails) public static Task APIRequestAsync(Tuple[] getParameters, Tuple[] postParameters) where K : Response { - RequestPath path = RequestPath.GetRequestPath(); + var path = RequestPath.GetRequestPath(); //TODO: Custom paths? Appropriate subdomain paths? Not sure. //Maybe store custom path in the requestpath.path itself? - Uri requestUri = SlackClient.GetSlackUri(Path.Combine(APIBaseLocation, path.Path), getParameters); - HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(requestUri); + var requestUri = SlackClient.GetSlackUri(Path.Combine(APIBaseLocation, path.Path), getParameters); + var request = (HttpWebRequest)HttpWebRequest.Create(requestUri); //This will handle all of the processing. var state = new RequestStateForTask(request, postParameters); @@ -122,11 +123,11 @@ public Task APIRequestWithTokenAsync() { return APIRequestWithTokenAsync(new Tuple[] { }); } - - public Task APIRequestWithTokenAsync(params Tuple[] postParameters) + + public Task APIRequestWithTokenAsync(params Tuple[] postParameters) where K : Response { - Tuple[] tokenArray = new Tuple[]{ + var tokenArray = new Tuple[]{ new Tuple("token", APIToken) }; @@ -143,13 +144,13 @@ public static Task FindTeam(string team) { //This seems to accept both 'team.slack.com' and just plain 'team'. //Going to go with the latter. - Tuple domainName = new Tuple("domain", team); + var domainName = new Tuple("domain", team); return APIRequestAsync(new Tuple[] { domainName }, new Tuple[0]); } public static Task AuthSignin(string userId, string teamId, string password) { - return APIRequestAsync(new Tuple[] { + return APIRequestAsync(new Tuple[] { new Tuple("user", userId), new Tuple("team", teamId), new Tuple("password", password) @@ -183,10 +184,10 @@ public Task GetDirectMessageListAsync() public Task GetFilesAsync(string userId = null, DateTime? from = null, DateTime? to = null, int? count = null, int? page = null, FileTypes types = FileTypes.all) { - List> parameters = new List>(); + var parameters = new List>(); if (!string.IsNullOrEmpty(userId)) - parameters.Add(new Tuple("user", userId)); + parameters.Add(new Tuple("user", userId)); if (from.HasValue) parameters.Add(new Tuple("ts_from", from.Value.ToProperTimeStamp())); @@ -196,11 +197,11 @@ public Task GetFilesAsync(string userId = null, DateTime? from if (!types.HasFlag(FileTypes.all)) { - FileTypes[] values = (FileTypes[])Enum.GetValues(typeof(FileTypes)); - - StringBuilder building = new StringBuilder(); - bool first = true; - for (int i = 0; i < values.Length; ++i) + var values = (FileTypes[])Enum.GetValues(typeof(FileTypes)); + + var building = new StringBuilder(); + var first = true; + for (var i = 0; i < values.Length; ++i) { if (types.HasFlag(values[i])) { @@ -228,15 +229,15 @@ public Task GetFilesAsync(string userId = null, DateTime? from private Task GetHistoryAsync(string channel, DateTime? latest = null, DateTime? oldest = null, int? count = null) where K : MessageHistory { - List> parameters = new List>(); + var parameters = new List>(); parameters.Add(new Tuple("channel", channel)); - - if(latest.HasValue) + + if (latest.HasValue) parameters.Add(new Tuple("latest", latest.Value.ToProperTimeStamp())); - if(oldest.HasValue) + if (oldest.HasValue) parameters.Add(new Tuple("oldest", oldest.Value.ToProperTimeStamp())); - if(count.HasValue) - parameters.Add(new Tuple("count", count.Value.ToString())); + if (count.HasValue) + parameters.Add(new Tuple("count", count.Value.ToString())); return APIRequestWithTokenAsync(parameters.ToArray()); } @@ -265,18 +266,19 @@ public Task MarkChannelAsync(string channelId, DateTime ts) public Task GetFileInfoAsync(string fileId, int? page = null, int? count = null) { - List> parameters = new List>(); + var parameters = new List>(); + + parameters.Add(new Tuple("file", fileId)); - parameters.Add(new Tuple("file", fileId)); - - if(count.HasValue) - parameters.Add(new Tuple("count", count.Value.ToString())); + if (count.HasValue) + parameters.Add(new Tuple("count", count.Value.ToString())); if (page.HasValue) parameters.Add(new Tuple("page", page.Value.ToString())); return APIRequestWithTokenAsync(parameters.ToArray()); } + #region Groups public Task GroupsArchiveAsync(string channelId) { @@ -300,7 +302,7 @@ public Task GroupsCreateChildAsync(string channelId) public Task GroupsInviteAsync(string userId, string channelId) { - List> parameters = new List>(); + var parameters = new List>(); parameters.Add(new Tuple("channel", channelId)); parameters.Add(new Tuple("user", userId)); @@ -310,7 +312,7 @@ public Task GroupsInviteAsync(string userId, string channel public Task GroupsKickAsync(string userId, string channelId) { - List> parameters = new List>(); + var parameters = new List>(); parameters.Add(new Tuple("channel", channelId)); parameters.Add(new Tuple("user", userId)); @@ -335,7 +337,7 @@ public Task GroupsOpenAsync(string channelId) public Task GroupsRenameAsync(string channelId, string name) { - List> parameters = new List>(); + var parameters = new List>(); parameters.Add(new Tuple("channel", channelId)); parameters.Add(new Tuple("name", name)); @@ -345,7 +347,7 @@ public Task GroupsRenameAsync(string channelId, string name public Task GroupsSetPurposeAsync(string channelId, string purpose) { - List> parameters = new List>(); + var parameters = new List>(); parameters.Add(new Tuple("channel", channelId)); parameters.Add(new Tuple("purpose", purpose)); @@ -355,7 +357,7 @@ public Task GroupsSetPurposeAsync(string channelId, str public Task GroupsSetTopicAsync(string channelId, string topic) { - List> parameters = new List>(); + var parameters = new List>(); parameters.Add(new Tuple("channel", channelId)); parameters.Add(new Tuple("topic", topic)); @@ -372,7 +374,7 @@ public Task GroupsUnarchiveAsync(string channelId) public Task SearchAllAsync(string query, SearchSort? sorting = null, SearchSortDirection? direction = null, bool enableHighlights = false, int? count = null, int? page = null) { - List> parameters = new List>(); + var parameters = new List>(); parameters.Add(new Tuple("query", query)); if (sorting.HasValue) @@ -395,7 +397,7 @@ public Task SearchAllAsync(string query, SearchSort? sorting public Task SearchMessagesAsync(string query, SearchSort? sorting = null, SearchSortDirection? direction = null, bool enableHighlights = false, int? count = null, int? page = null) { - List> parameters = new List>(); + var parameters = new List>(); parameters.Add(new Tuple("query", query)); if (sorting.HasValue) @@ -418,7 +420,7 @@ public Task SearchMessagesAsync(string query, SearchSort public Task SearchFilesAsync(string query, SearchSort? sorting = null, SearchSortDirection? direction = null, bool enableHighlights = false, int? count = null, int? page = null) { - List> parameters = new List>(); + var parameters = new List>(); parameters.Add(new Tuple("query", query)); if (sorting.HasValue) @@ -439,24 +441,25 @@ public Task SearchFilesAsync(string query, SearchSort? sort return APIRequestWithTokenAsync(parameters.ToArray()); } - public Task GetStarsAsync(string userId = null, int? count = null, int? page = null){ - List> parameters = new List>(); - - if(!string.IsNullOrEmpty(userId)) - parameters.Add(new Tuple("user", userId)); + public Task GetStarsAsync(string userId = null, int? count = null, int? page = null) + { + var parameters = new List>(); + + if (!string.IsNullOrEmpty(userId)) + parameters.Add(new Tuple("user", userId)); - if(count.HasValue) - parameters.Add(new Tuple("count", count.Value.ToString())); + if (count.HasValue) + parameters.Add(new Tuple("count", count.Value.ToString())); - if(page.HasValue) - parameters.Add(new Tuple("page", page.Value.ToString())); + if (page.HasValue) + parameters.Add(new Tuple("page", page.Value.ToString())); return APIRequestWithTokenAsync(parameters.ToArray()); } public Task DeleteMessageAsync(string channelId, DateTime ts) { - List> parameters = new List>() + var parameters = new List>() { new Tuple("ts", ts.ToProperTimeStamp()), new Tuple("channel", channelId) @@ -503,13 +506,13 @@ public Task PostMessageAsync( string icon_emoji = null, bool as_user = false) { - List> parameters = new List>(); + var parameters = new List>(); - parameters.Add(new Tuple("channel", channelId)); - parameters.Add(new Tuple("text", text)); + parameters.Add(new Tuple("channel", channelId)); + parameters.Add(new Tuple("text", text)); - if(!string.IsNullOrEmpty(botName)) - parameters.Add(new Tuple("username", botName)); + if (!string.IsNullOrEmpty(botName)) + parameters.Add(new Tuple("username", botName)); if (!string.IsNullOrEmpty(parse)) parameters.Add(new Tuple("parse", parse)); @@ -536,12 +539,12 @@ public Task PostMessageAsync( public Task UploadFileAsync(byte[] fileData, string fileName, string[] channelIds, string title = null, string initialComment = null, bool useAsync = false, string fileType = null) { - Uri target = new Uri(Path.Combine(APIBaseLocation, useAsync ? "files.uploadAsync" : "files.upload")); + var target = new Uri(Path.Combine(APIBaseLocation, useAsync ? "files.uploadAsync" : "files.upload")); - List parameters = new List(); + var parameters = new List(); parameters.Add(string.Format("token={0}", APIToken)); - //File/Content + // File/Content if (!string.IsNullOrEmpty(fileType)) parameters.Add(string.Format("{0}={1}", "filetype", fileType)); @@ -556,12 +559,12 @@ public Task UploadFileAsync(byte[] fileData, string fileName parameters.Add(string.Format("{0}={1}", "channels", string.Join(",", channelIds))); - using(HttpClient client = new HttpClient()) - using (MultipartFormDataContent form = new MultipartFormDataContent()) + using (var client = new HttpClient()) + using (var form = new MultipartFormDataContent()) { form.Add(new ByteArrayContent(fileData), "file", fileName); - HttpResponseMessage response = client.PostAsync(string.Format("{0}?{1}", target, string.Join("&", parameters.ToArray())), form).Result; - string result = response.Content.ReadAsStringAsync().Result; + var response = client.PostAsync(string.Format("{0}?{1}", target, string.Join("&", parameters.ToArray())), form).Result; + var result = response.Content.ReadAsStringAsync().Result; //callback(JsonConvert.DeserializeObject(result, new JavascriptDateTimeConverter())); throw new NotImplementedException("This operation has not been implemented."); } @@ -570,8 +573,150 @@ public Task UploadFileAsync(byte[] fileData, string fileName public Task ChannelSetTopicAsync(string channelId, string newTopic) { return APIRequestWithTokenAsync( - new Tuple("channel", channelId), - new Tuple("topic", newTopic)); + new Tuple("channel", channelId), + new Tuple("topic", newTopic)); + } + + #region Channel + + public Task ChannelsCreateAsync(string name) + { + return APIRequestWithTokenAsync(new Tuple("name", name)); + } + + public Task ChannelsInviteAsync(string userId, string channelId) + { + var parameters = new List>() + { + new Tuple("channel", channelId), + new Tuple("user", userId), + }; + return APIRequestWithTokenAsync(parameters.ToArray()); + } + + public Task ChannelsSetPurposeAsync(string channelId, string purpose) + { + var parameters = new List>() + { + new Tuple("channel", channelId), + new Tuple("purpose", purpose), + }; + return APIRequestWithTokenAsync(parameters.ToArray()); + } + + public Task ChannelsRenameAsync(string channelId, string name) + { + var parameters = new List>() + { + new Tuple("channel", channelId), + new Tuple("name", name), + }; + return APIRequestWithTokenAsync(parameters.ToArray()); + } + + public Task ChannelsArchiveAsync(string channelId) + { + return APIRequestWithTokenAsync(new Tuple("channel", channelId)); + } + + public Task ChannelsUnarchiveAsync(string channelId) + { + return APIRequestWithTokenAsync(new Tuple("channel", channelId)); } + + #endregion + + #region Pin + + public Task PinsListAsync(string channelId) + { + var parameters = new List>() + { + new Tuple("channel", channelId), + }; + return APIRequestWithTokenAsync(parameters.ToArray()); + } + + public Task PinsRemoveAsync(string channelId, long? timestamp) + { + var parameters = new List>() + { + new Tuple("channel", channelId), + new Tuple("timestamp", (timestamp != null ? timestamp.Value.ToString() : null)), + }; + return APIRequestWithTokenAsync(parameters.ToArray()); + } + + #endregion + + #region User + + // https://levels.io/slack-typeform-auto-invite-sign-ups/ + public Task AddUserAsync(string email, string firstName, bool restricted, string[] channelIds) + { + var parameters = new List>() + { + new Tuple("email", email), + new Tuple("first_name", firstName), + new Tuple("channels", (channelIds != null ? string.Join(",", channelIds) : null)) + }; + if (restricted) + parameters.Add(new Tuple("restricted", "1")); + return APIRequestWithTokenAsync(parameters.ToArray()); + } + + public Task DeleteUserAsync(string userId) + { + var parameters = new List>() + { + new Tuple("userId", userId) + }; + return APIRequestWithTokenAsync(parameters.ToArray()); + } + + public Task SetInactiveUserAsync(string userId) + { + var parameters = new List>() + { + new Tuple("user", userId), + new Tuple("set_active", "true") + }; + return APIRequestWithTokenAsync(parameters.ToArray()); + } + + public Task SetUserProfileEmailAsync(string userId, string email) + { + var parameters = new List>() + { + new Tuple("user", userId), + new Tuple("profile", "{\"email\":\"" + email + "\"}"), + new Tuple("set_active", "true") + }; + return APIRequestWithTokenAsync(parameters.ToArray()); + } + + public Task SetUserProfileFullNameAsync(string userId, string firstName, string lastName) + { + var parameters = new List>() + { + new Tuple("user", userId), + new Tuple("profile", "{\"first_name\":\"" + firstName + "\",\"last_name\": \"" + lastName +"\"}"), + new Tuple("set_active", "true") + }; + return APIRequestWithTokenAsync(parameters.ToArray()); + } + + public Task SetUserProfileUserNameAsync(string userId, string userName) + { + var parameters = new List>() + { + new Tuple("user", userId), + new Tuple("profile", "{\"username\":\"" + userName + "\"}"), + new Tuple("set_active", "true") + }; + return APIRequestWithTokenAsync(parameters.ToArray()); + } + + #endregion } } \ No newline at end of file diff --git a/SlackAPI/TeamPreferences.cs b/SlackAPI/TeamPreferences.cs index c7da545..58b08b2 100644 --- a/SlackAPI/TeamPreferences.cs +++ b/SlackAPI/TeamPreferences.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { public class TeamPreferences { diff --git a/SlackAPI/User.cs b/SlackAPI/User.cs index eba1f1a..a756316 100644 --- a/SlackAPI/User.cs +++ b/SlackAPI/User.cs @@ -1,8 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace SlackAPI { diff --git a/SlackAPI/UserProfile.cs b/SlackAPI/UserProfile.cs index d6579ad..cf184ee 100644 --- a/SlackAPI/UserProfile.cs +++ b/SlackAPI/UserProfile.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { public class UserProfile { @@ -21,10 +15,24 @@ public class UserProfile public string image_48; public string image_72; public string image_192; + public string image_512; public override string ToString() { return real_name; } + + public string image_max + { + get + { + if (!string.IsNullOrEmpty(image_512)) return image_512; + if (!string.IsNullOrEmpty(image_192)) return image_192; + if (!string.IsNullOrEmpty(image_72)) return image_72; + if (!string.IsNullOrEmpty(image_32)) return image_32; + if (!string.IsNullOrEmpty(image_24)) return image_24; + return null; + } + } } } diff --git a/SlackAPI/UserTeamCombo.cs b/SlackAPI/UserTeamCombo.cs index 95a19c7..87a58fb 100644 --- a/SlackAPI/UserTeamCombo.cs +++ b/SlackAPI/UserTeamCombo.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI +namespace SlackAPI { public class UserTeamCombo { diff --git a/SlackAPI/Utilities/ILockFree.cs b/SlackAPI/Utilities/ILockFree.cs index 781e073..5f7bdbf 100644 --- a/SlackAPI/Utilities/ILockFree.cs +++ b/SlackAPI/Utilities/ILockFree.cs @@ -1,6 +1,4 @@ -using System; - -namespace SlackAPI.Utilities +namespace SlackAPI.Utilities { public abstract class ILockFree where T : class { diff --git a/SlackAPI/Utilities/LockFreeQueue.cs b/SlackAPI/Utilities/LockFreeQueue.cs index 824c72e..1b057ea 100644 --- a/SlackAPI/Utilities/LockFreeQueue.cs +++ b/SlackAPI/Utilities/LockFreeQueue.cs @@ -37,10 +37,10 @@ public void Unshift(T pItem) { SingleLinkNode oldHead = null; - SingleLinkNode newNode = new SingleLinkNode(); + var newNode = new SingleLinkNode(); newNode.Item = pItem; - bool newNodeWasAdded = false; + var newNodeWasAdded = false; while (!newNodeWasAdded) { oldHead = mHead.Next; @@ -57,10 +57,10 @@ public override void Push(T pItem) SingleLinkNode oldTail = null; SingleLinkNode oldTailNext; - SingleLinkNode newNode = new SingleLinkNode(); + var newNode = new SingleLinkNode(); newNode.Item = pItem; - bool newNodeWasAdded = false; + var newNodeWasAdded = false; while (!newNodeWasAdded) { oldTail = mTail; @@ -82,12 +82,12 @@ public override bool Pop(out T pItem) pItem = default(T); SingleLinkNode oldHead = null; - bool haveAdvancedHead = false; + var haveAdvancedHead = false; while (!haveAdvancedHead) { oldHead = mHead; - SingleLinkNode oldTail = mTail; - SingleLinkNode oldHeadNext = oldHead.Next; + var oldTail = mTail; + var oldHeadNext = oldHead.Next; if (oldHead == mHead) { @@ -124,13 +124,13 @@ public bool Shift(out T pItem) return false; SingleLinkNode oldHead = null; - bool haveAdvancedHead = false; + var haveAdvancedHead = false; while (!haveAdvancedHead) { oldHead = mHead; if (oldHead != null) { - SingleLinkNode oldHeadNext = oldHead.Next; + var oldHeadNext = oldHead.Next; if (CompareAndExchange(ref mHead, oldHead, oldHeadNext)) { pItem = oldHead.Item; diff --git a/SlackAPI/WebSocketMessages/GroupJoined.cs b/SlackAPI/WebSocketMessages/GroupJoined.cs index 12518c9..30b354a 100644 --- a/SlackAPI/WebSocketMessages/GroupJoined.cs +++ b/SlackAPI/WebSocketMessages/GroupJoined.cs @@ -6,4 +6,3 @@ public class GroupJoined : SlackSocketMessage public Channel channel; } } - diff --git a/SlackAPI/WebSocketMessages/GroupLeft.cs b/SlackAPI/WebSocketMessages/GroupLeft.cs index 988bbd3..170d0f8 100644 --- a/SlackAPI/WebSocketMessages/GroupLeft.cs +++ b/SlackAPI/WebSocketMessages/GroupLeft.cs @@ -6,4 +6,3 @@ public class GroupLeft : SlackSocketMessage public string channel; } } - diff --git a/SlackAPI/WebSocketMessages/GroupOpen.cs b/SlackAPI/WebSocketMessages/GroupOpen.cs index e86a7fe..97c1a0e 100644 --- a/SlackAPI/WebSocketMessages/GroupOpen.cs +++ b/SlackAPI/WebSocketMessages/GroupOpen.cs @@ -7,4 +7,3 @@ public class GroupOpen : SlackSocketMessage public string channel; } } - diff --git a/SlackAPI/WebSocketMessages/GroupRename.cs b/SlackAPI/WebSocketMessages/GroupRename.cs index 13a5a46..9208b81 100644 --- a/SlackAPI/WebSocketMessages/GroupRename.cs +++ b/SlackAPI/WebSocketMessages/GroupRename.cs @@ -6,4 +6,3 @@ public class GroupRename : SlackSocketMessage public Channel channel; } } - diff --git a/SlackAPI/WebSocketMessages/GroupUnarchive.cs b/SlackAPI/WebSocketMessages/GroupUnarchive.cs index 37a69d5..db6d0d7 100644 --- a/SlackAPI/WebSocketMessages/GroupUnarchive.cs +++ b/SlackAPI/WebSocketMessages/GroupUnarchive.cs @@ -6,4 +6,3 @@ public class GroupUnarchive : SlackSocketMessage public string channel; } } - diff --git a/SlackAPI/WebSocketMessages/Hello.cs b/SlackAPI/WebSocketMessages/Hello.cs index beb4825..e561dd9 100644 --- a/SlackAPI/WebSocketMessages/Hello.cs +++ b/SlackAPI/WebSocketMessages/Hello.cs @@ -1,6 +1,4 @@ -using System; - -namespace SlackAPI.WebSocketMessages +namespace SlackAPI.WebSocketMessages { [SlackSocketRouting("hello")] public class Hello : SlackSocketMessage diff --git a/SlackAPI/WebSocketMessages/Ping.cs b/SlackAPI/WebSocketMessages/Ping.cs index 0132253..42a4bb6 100644 --- a/SlackAPI/WebSocketMessages/Ping.cs +++ b/SlackAPI/WebSocketMessages/Ping.cs @@ -1,6 +1,4 @@ -using System; - -namespace SlackAPI.WebSocketMessages +namespace SlackAPI.WebSocketMessages { [SlackSocketRouting("ping")] public class Ping : SlackSocketMessage diff --git a/SlackAPI/WebSocketMessages/Pong.cs b/SlackAPI/WebSocketMessages/Pong.cs index 6979303..571ccad 100644 --- a/SlackAPI/WebSocketMessages/Pong.cs +++ b/SlackAPI/WebSocketMessages/Pong.cs @@ -1,6 +1,4 @@ -using System; - -namespace SlackAPI.WebSocketMessages +namespace SlackAPI.WebSocketMessages { [SlackSocketRouting("pong")] public class Pong : SlackSocketMessage diff --git a/SlackAPI/WebSocketMessages/PresenceChange.cs b/SlackAPI/WebSocketMessages/PresenceChange.cs index cf8578a..1cbb2e1 100644 --- a/SlackAPI/WebSocketMessages/PresenceChange.cs +++ b/SlackAPI/WebSocketMessages/PresenceChange.cs @@ -1,6 +1,4 @@ -using System; - -namespace SlackAPI.WebSocketMessages +namespace SlackAPI.WebSocketMessages { [SlackSocketRouting("presence_change")] public class PresenceChange : SlackSocketMessage diff --git a/SlackAPI/WebSocketMessages/PresenceSub.cs b/SlackAPI/WebSocketMessages/PresenceSub.cs new file mode 100644 index 0000000..db9cec3 --- /dev/null +++ b/SlackAPI/WebSocketMessages/PresenceSub.cs @@ -0,0 +1,8 @@ +namespace SlackAPI.WebSocketMessages +{ + [SlackSocketRouting("presence_sub")] + public class PresenceSub : SlackSocketMessage + { + public string[] ids; + } +} diff --git a/SlackAPI/WebSocketMessages/ReactionAdded.cs b/SlackAPI/WebSocketMessages/ReactionAdded.cs index 277e721..69c0784 100644 --- a/SlackAPI/WebSocketMessages/ReactionAdded.cs +++ b/SlackAPI/WebSocketMessages/ReactionAdded.cs @@ -1,11 +1,4 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SlackAPI.WebSocketMessages +namespace SlackAPI.WebSocketMessages { [SlackSocketRouting("reaction_added")] public class ReactionAdded : SlackSocketMessage @@ -28,4 +21,3 @@ public class Item public string ts; } } - diff --git a/SlackAPI/WebSocketMessages/Typing.cs b/SlackAPI/WebSocketMessages/Typing.cs index 2979409..55e0bd1 100644 --- a/SlackAPI/WebSocketMessages/Typing.cs +++ b/SlackAPI/WebSocketMessages/Typing.cs @@ -1,6 +1,4 @@ -using System; - -namespace SlackAPI.WebSocketMessages +namespace SlackAPI.WebSocketMessages { [SlackSocketRouting("typing")] [SlackSocketRouting("user_typing")] diff --git a/SlackAPI/WebSocketMessages/UserChange.cs b/SlackAPI/WebSocketMessages/UserChange.cs index 9bbac45..abe68ed 100644 --- a/SlackAPI/WebSocketMessages/UserChange.cs +++ b/SlackAPI/WebSocketMessages/UserChange.cs @@ -6,4 +6,3 @@ public class UserChange : SlackSocketMessage public User user; } } - diff --git a/appveyor.yml b/appveyor.yml index b9c5120..d967ce1 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -17,7 +17,7 @@ before_build: "slack": { "userAuthToken": "$env:userAuthToken", "botAuthToken": "$env:botAuthToken", - "testChannel": "$env:testChannel", + "testChannelId": "$env:testChannel", "directMessageUser": "$env:directMessageUser", "authCode": "$env:authCode", "clientId": "$env:clientId",