OSDN Git Service

HttpTwitter.RateLimitStatusメソッドをTwitterApiクラスに置き換え
authorKimura Youichi <kim.upsilon@bucyou.net>
Wed, 4 May 2016 14:25:59 +0000 (23:25 +0900)
committerKimura Youichi <kim.upsilon@bucyou.net>
Wed, 4 May 2016 15:56:42 +0000 (00:56 +0900)
OpenTween.Tests/Api/TwitterApiStatusTest.cs
OpenTween.Tests/Api/TwitterApiTest.cs
OpenTween/Api/DataModel/TwitterRateLimits.cs [new file with mode: 0644]
OpenTween/Api/TwitterApi.cs
OpenTween/Api/TwitterApiStatus.cs
OpenTween/Connection/HttpTwitter.cs
OpenTween/MyCommon.cs
OpenTween/OpenTween.csproj
OpenTween/Tween.cs
OpenTween/Twitter.cs

index 394a604..7ff71d2 100644 (file)
@@ -243,7 +243,6 @@ namespace OpenTween.Api
             Assert.True(eventCalled);
         }
 
-        [Fact(Skip = "Mono環境でエラーが発生する")]
         public void UpdateFromJsonTest()
         {
             var status = new TwitterApiStatus();
@@ -252,7 +251,7 @@ namespace OpenTween.Api
             status.AccessLimitUpdated += (s, e) => eventCalled = true;
 
             var json = "{\"resources\":{\"statuses\":{\"/statuses/home_timeline\":{\"limit\":150,\"remaining\":100,\"reset\":1356998400}}}}";
-            status.UpdateFromJson(json);
+            status.UpdateFromJson(TwitterRateLimits.ParseJson(json));
 
             var rateLimit = status.AccessLimit["/statuses/home_timeline"];
             Assert.Equal(150, rateLimit.AccessLimitCount);
@@ -263,23 +262,6 @@ namespace OpenTween.Api
         }
 
         [Fact]
-        public void UpdateFromJsonTest2()
-        {
-            var status = new TwitterApiStatus();
-
-            var eventCalled = false;
-            status.AccessLimitUpdated += (s, e) => eventCalled = true;
-
-            var json = "INVALID JSON";
-            Assert.Throws<XmlException>(() => status.UpdateFromJson(json));
-
-            var rateLimit = status.AccessLimit["/statuses/home_timeline"];
-            Assert.Null(rateLimit);
-
-            Assert.False(eventCalled);
-        }
-
-        [Fact]
         public void AccessLimitUpdatedTest()
         {
             var apiStatus = new TwitterApiStatus();
index db7a11d..273ff89 100644 (file)
@@ -783,6 +783,29 @@ namespace OpenTween.Api
         }
 
         [Fact]
+        public async Task ApplicationRateLimitStatus_Test()
+        {
+            using (var twitterApi = new TwitterApi())
+            {
+                var mock = new Mock<IApiConnection>();
+                mock.Setup(x =>
+                    x.GetAsync<TwitterRateLimits>(
+                        new Uri("application/rate_limit_status.json", UriKind.Relative),
+                        null,
+                        "/application/rate_limit_status")
+                )
+                .ReturnsAsync(new TwitterRateLimits());
+
+                twitterApi.apiConnection = mock.Object;
+
+                await twitterApi.ApplicationRateLimitStatus()
+                    .ConfigureAwait(false);
+
+                mock.VerifyAll();
+            }
+        }
+
+        [Fact]
         public async Task Configuration_Test()
         {
             using (var twitterApi = new TwitterApi())
diff --git a/OpenTween/Api/DataModel/TwitterRateLimits.cs b/OpenTween/Api/DataModel/TwitterRateLimits.cs
new file mode 100644 (file)
index 0000000..5a3538f
--- /dev/null
@@ -0,0 +1,66 @@
+// OpenTween - Client of Twitter
+// Copyright (c) 2016 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
+// All rights reserved.
+//
+// This file is part of OpenTween.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program. If not, see <http://www.gnu.org/licenses/>, or write to
+// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.Serialization;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace OpenTween.Api.DataModel
+{
+    [DataContract]
+    public class TwitterRateLimits
+    {
+        [DataMember(Name = "rate_limit_context")]
+        public TwitterRateLimitContext RateLimitContext { get; set; }
+
+        [DataContract]
+        public class TwitterRateLimitContext
+        {
+            [DataMember(Name = "access_token")]
+            public string AccessToken { get; set; }
+        }
+
+        [DataMember(Name = "resources")]
+        public IDictionary<string, IDictionary<string, TwitterRateLimit>> Resources { get; set; }
+
+        [DataContract]
+        public class TwitterRateLimit
+        {
+            [DataMember(Name = "limit")]
+            public int Limit { get; set; }
+
+            [DataMember(Name = "remaining")]
+            public int Remaining { get; set; }
+
+            [DataMember(Name = "reset")]
+            public long Reset { get; set; }
+        }
+
+        /// <exception cref="SerializationException"/>
+        public static TwitterRateLimits ParseJson(string json)
+        {
+            return MyCommon.CreateDataFromJson<TwitterRateLimits>(json);
+        }
+    }
+}
index a5c134d..52f7572 100644 (file)
@@ -434,6 +434,13 @@ namespace OpenTween.Api
             return this.apiConnection.PostLazyAsync<TwitterUser>(endpoint, param, paramMedia);
         }
 
+        public Task<TwitterRateLimits> ApplicationRateLimitStatus()
+        {
+            var endpoint = new Uri("application/rate_limit_status.json", UriKind.Relative);
+
+            return this.apiConnection.GetAsync<TwitterRateLimits>(endpoint, null, "/application/rate_limit_status");
+        }
+
         public Task<TwitterConfiguration> Configuration()
         {
             var endpoint = new Uri("help/configuration.json", UriKind.Relative);
index 6190e82..12e40e4 100644 (file)
@@ -136,25 +136,21 @@ namespace OpenTween.Api
 
         private static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
 
-        public void UpdateFromJson(string json)
+        public void UpdateFromJson(TwitterRateLimits json)
         {
-            using (var jsonReader = JsonReaderWriterFactory.CreateJsonReader(Encoding.UTF8.GetBytes(json), XmlDictionaryReaderQuotas.Max))
-            {
-                var xElm = XElement.Load(jsonReader);
-                XNamespace a = "item";
-
-                var q =
-                    from res in xElm.Element("resources").Descendants(a + "item") // a:item 要素を列挙
-                    select new {
-                        endpointName = res.Attribute("item").Value,
-                        limit = new ApiLimit(
-                            int.Parse(res.Element("limit").Value),
-                            int.Parse(res.Element("remaining").Value),
-                            UnixEpoch.AddSeconds(long.Parse(res.Element("reset").Value)).ToLocalTime()
-                        ),
-                    };
-                this.AccessLimit.AddAll(q.ToDictionary(x => x.endpointName, x => x.limit));
-            }
+            var rateLimits =
+                from res in json.Resources
+                from item in res.Value
+                select new {
+                    endpointName = item.Key,
+                    limit = new ApiLimit(
+                        item.Value.Limit,
+                        item.Value.Remaining,
+                        UnixEpoch.AddSeconds(item.Value.Reset).ToLocalTime()
+                    ),
+                };
+
+            this.AccessLimit.AddAll(rateLimits.ToDictionary(x => x.endpointName, x => x.limit));
         }
 
         protected virtual void OnAccessLimitUpdated(AccessLimitUpdatedEventArgs e)
index a4c0775..fc7b875 100644 (file)
@@ -200,16 +200,6 @@ namespace OpenTween
                 this.CreateApiCalllback("/saved_searches/list"));
         }
 
-        public HttpStatusCode RateLimitStatus(ref string content)
-        {
-            return httpCon.GetContent(GetMethod,
-                this.CreateTwitterUri("/1.1/application/rate_limit_status.json"),
-                null,
-                ref content,
-                this.CreateRatelimitHeadersDict(),
-                this.CreateApiCalllback("/application/rate_limit_status"));
-        }
-
         #region Lists
         public HttpStatusCode GetLists(string user, ref string content)
         {
index fb6631c..c48f222 100644 (file)
@@ -843,7 +843,11 @@ namespace OpenTween
             var buf = Encoding.Unicode.GetBytes(content);
             using (var stream = new MemoryStream(buf))
             {
-                data = (T)((new DataContractJsonSerializer(typeof(T))).ReadObject(stream));
+                var settings = new DataContractJsonSerializerSettings
+                {
+                    UseSimpleDictionaryFormat = true,
+                };
+                data = (T)((new DataContractJsonSerializer(typeof(T), settings)).ReadObject(stream));
             }
             return data;
         }
index 8fd4f0d..244f7b6 100644 (file)
@@ -79,6 +79,7 @@
       <SubType>Code</SubType>
     </Compile>
     <Compile Include="Api\DataModel\TwitterPlace.cs" />
+    <Compile Include="Api\DataModel\TwitterRateLimits.cs" />
     <Compile Include="Api\DataModel\TwitterSearchResult.cs" />
     <Compile Include="Api\DataModel\TwitterStatus.cs" />
     <Compile Include="Api\DataModel\TwitterStreamEvent.cs" />
index 1b489d3..54adcba 100644 (file)
@@ -11332,7 +11332,7 @@ namespace OpenTween
 
                 try
                 {
-                    var task = Task.Run(() => this.tw.GetInfoApi());
+                    var task = this.tw.GetInfoApi();
                     apiStatus = await dialog.WaitForAsync(this, task);
                 }
                 catch (WebApiException)
index 8164724..9e65c0d 100644 (file)
@@ -2061,37 +2061,18 @@ namespace OpenTween
             return Tuple.Create(sourceText, sourceUri);
         }
 
-        public TwitterApiStatus GetInfoApi()
+        public async Task<TwitterApiStatus> GetInfoApi()
         {
             if (Twitter.AccountState != MyCommon.ACCOUNT_STATE.Valid) return null;
 
             if (MyCommon._endingFlag) return null;
 
-            HttpStatusCode res;
-            var content = "";
-            try
-            {
-                res = twCon.RateLimitStatus(ref content);
-            }
-            catch (Exception)
-            {
-                this.ResetApiStatus();
-                return null;
-            }
+            var limits = await this.Api.ApplicationRateLimitStatus()
+                .ConfigureAwait(false);
 
-            this.CheckStatusCode(res, content);
+            MyCommon.TwitterApiInfo.UpdateFromJson(limits);
 
-            try
-            {
-                MyCommon.TwitterApiInfo.UpdateFromJson(content);
-                return MyCommon.TwitterApiInfo;
-            }
-            catch (Exception ex)
-            {
-                MyCommon.TraceOut(ex, MethodBase.GetCurrentMethod().Name + " " + content);
-                MyCommon.TwitterApiInfo.Reset();
-                return null;
-            }
+            return MyCommon.TwitterApiInfo;
         }
 
         /// <summary>