OSDN Git Service

Twitter.GetHomeTimelineApiメソッドをISocialProtocolQueryの各実装クラスに移動
authorKimura Youichi <kim.upsilon@bucyou.net>
Tue, 7 May 2024 16:14:28 +0000 (01:14 +0900)
committerKimura Youichi <kim.upsilon@bucyou.net>
Tue, 7 May 2024 17:44:17 +0000 (02:44 +0900)
OpenTween.Tests/SocialProtocol/Twitter/TwitterAccountTest.cs
OpenTween/Models/HomeTabModel.cs
OpenTween/SocialProtocol/ISocialAccount.cs
OpenTween/SocialProtocol/ISocialProtocolQuery.cs [new file with mode: 0644]
OpenTween/SocialProtocol/Twitter/TwitterAccount.cs
OpenTween/SocialProtocol/Twitter/TwitterGraphqlQuery.cs [new file with mode: 0644]
OpenTween/SocialProtocol/Twitter/TwitterV1Query.cs [new file with mode: 0644]
OpenTween/Twitter.cs

index d820796..02922b3 100644 (file)
@@ -81,5 +81,46 @@ namespace OpenTween.SocialProtocol.Twitter
             account.Initialize(accountSettings2, settingCommon2);
             Assert.Equal(22222L, account.UserId);
         }
+
+        [Fact]
+        public void Query_V1_Test()
+        {
+            var accountKey = Guid.NewGuid();
+            using var account = new TwitterAccount(accountKey);
+
+            var accountSettings = new UserAccount
+            {
+                UniqueKey = accountKey,
+                TwitterAuthType = APIAuthType.OAuth1,
+                Token = "aaaaa",
+                TokenSecret = "aaaaa",
+                UserId = 11111L,
+                Username = "tetete",
+            };
+            var settingCommon = new SettingCommon();
+            account.Initialize(accountSettings, settingCommon);
+
+            Assert.IsType<TwitterV1Query>(account.Query);
+        }
+
+        [Fact]
+        public void Query_Graphql_Test()
+        {
+            var accountKey = Guid.NewGuid();
+            using var account = new TwitterAccount(accountKey);
+
+            var accountSettings = new UserAccount
+            {
+                UniqueKey = accountKey,
+                TwitterAuthType = APIAuthType.TwitterComCookie,
+                TwitterComCookie = "auth_token=foo; ct0=bar",
+                UserId = 11111L,
+                Username = "tetete",
+            };
+            var settingCommon = new SettingCommon();
+            account.Initialize(accountSettings, settingCommon);
+
+            Assert.IsType<TwitterGraphqlQuery>(account.Query);
+        }
     }
 }
index 53705ce..ea785d9 100644 (file)
@@ -69,16 +69,13 @@ namespace OpenTween.Models
 
         public override async Task RefreshAsync(ISocialAccount account, bool backward, IProgress<string> progress)
         {
-            if (account is not TwitterAccount twAccount)
-                throw new ArgumentException($"Invalid account type: {account.GetType()}", nameof(account));
-
             progress.Report(string.Format(Properties.Resources.GetTimelineWorker_RunWorkerCompletedText5, backward ? -1 : 1));
 
             var firstLoad = !this.IsFirstLoadCompleted;
             var count = Twitter.GetApiResultCount(MyCommon.WORKERTYPE.Timeline, backward, firstLoad);
             var cursor = backward ? this.CursorBottom : this.CursorTop;
 
-            var response = await twAccount.Legacy.GetHomeTimelineApi(count, cursor, firstLoad)
+            var response = await account.Query.GetHomeTimeline(count, cursor, firstLoad)
                 .ConfigureAwait(false);
 
             foreach (var post in response.Posts)
index a69ae0b..6aa0b8c 100644 (file)
@@ -36,6 +36,8 @@ namespace OpenTween.SocialProtocol
 
         public IApiConnection Connection { get; }
 
+        public ISocialProtocolQuery Query { get; }
+
         public bool IsDisposed { get; }
 
         public void Initialize(UserAccount accountSettings, SettingCommon settingCommon);
diff --git a/OpenTween/SocialProtocol/ISocialProtocolQuery.cs b/OpenTween/SocialProtocol/ISocialProtocolQuery.cs
new file mode 100644 (file)
index 0000000..85e2ba4
--- /dev/null
@@ -0,0 +1,33 @@
+// OpenTween - Client of Twitter
+// Copyright (c) 2024 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.
+
+#nullable enable
+
+using System.Threading.Tasks;
+using OpenTween.Models;
+
+namespace OpenTween.SocialProtocol
+{
+    public interface ISocialProtocolQuery
+    {
+        public Task<TimelineResponse> GetHomeTimeline(int count, IQueryCursor? cursor, bool firstLoad);
+    }
+}
index 9621459..6ae5e5d 100644 (file)
@@ -33,6 +33,8 @@ namespace OpenTween.SocialProtocol.Twitter
 
         public Guid UniqueKey { get; }
 
+        public ISocialProtocolQuery Query { get; private set; }
+
         public bool IsDisposed { get; private set; }
 
         public TwitterAccountState AccountState { get; private set; } = new();
@@ -53,7 +55,10 @@ namespace OpenTween.SocialProtocol.Twitter
             => this.Legacy.Api.Connection;
 
         public TwitterAccount(Guid uniqueKey)
-            => this.UniqueKey = uniqueKey;
+        {
+            this.UniqueKey = uniqueKey;
+            this.Query = this.CreateQueryInstance(APIAuthType.None);
+        }
 
         public void Initialize(UserAccount accountSettings, SettingCommon settingCommon)
         {
@@ -61,6 +66,8 @@ namespace OpenTween.SocialProtocol.Twitter
 
             var credential = accountSettings.GetTwitterCredential();
             this.AccountState = new TwitterAccountState(accountSettings.UserId, accountSettings.Username);
+            this.Query = this.CreateQueryInstance(credential.AuthType);
+
             this.twLegacy.Initialize(credential, this.AccountState);
             this.twLegacy.RestrictFavCheck = settingCommon.RestrictFavCheck;
         }
@@ -73,5 +80,14 @@ namespace OpenTween.SocialProtocol.Twitter
             this.twLegacy.Dispose();
             this.IsDisposed = true;
         }
+
+        private ISocialProtocolQuery CreateQueryInstance(APIAuthType authType)
+        {
+            return authType switch
+            {
+                APIAuthType.TwitterComCookie => new TwitterGraphqlQuery(this),
+                _ => new TwitterV1Query(this),
+            };
+        }
     }
 }
diff --git a/OpenTween/SocialProtocol/Twitter/TwitterGraphqlQuery.cs b/OpenTween/SocialProtocol/Twitter/TwitterGraphqlQuery.cs
new file mode 100644 (file)
index 0000000..aa6b6e2
--- /dev/null
@@ -0,0 +1,68 @@
+// OpenTween - Client of Twitter
+// Copyright (c) 2007-2011 kiri_feather (@kiri_feather) <kiri.feather@gmail.com>
+//           (c) 2008-2011 Moz (@syo68k)
+//           (c) 2008-2011 takeshik (@takeshik) <http://www.takeshik.org/>
+//           (c) 2010-2011 anis774 (@anis774) <http://d.hatena.ne.jp/anis774/>
+//           (c) 2010-2011 fantasticswallow (@f_swallow) <http://twitter.com/f_swallow>
+//           (c) 2011      Egtra (@egtra) <http://dev.activebasic.com/egtra/>
+//           (c) 2013      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.
+
+#nullable enable
+
+using System.Threading.Tasks;
+using OpenTween.Api.GraphQL;
+using OpenTween.Models;
+
+namespace OpenTween.SocialProtocol.Twitter
+{
+    public class TwitterGraphqlQuery : ISocialProtocolQuery
+    {
+        private readonly TwitterAccount account;
+
+        public TwitterGraphqlQuery(TwitterAccount account)
+        {
+            this.account = account;
+        }
+
+        public async Task<TimelineResponse> GetHomeTimeline(int count, IQueryCursor? cursor, bool firstLoad)
+        {
+            this.account.Legacy.CheckAccountState();
+
+            var request = new HomeLatestTimelineRequest
+            {
+                Count = count,
+                Cursor = cursor?.As<TwitterGraphqlCursor>(),
+            };
+
+            var response = await request.Send(this.account.Connection)
+                .ConfigureAwait(false);
+
+            var statuses = response.ToTwitterStatuses();
+            var cursorTop = response.CursorTop;
+            var cursorBottom = response.CursorBottom;
+
+            var posts = this.account.Legacy.CreatePostsFromJson(statuses, firstLoad);
+            posts = this.account.Legacy.FilterNoRetweetUserPosts(posts);
+
+            return new(posts, cursorTop, cursorBottom);
+        }
+    }
+}
diff --git a/OpenTween/SocialProtocol/Twitter/TwitterV1Query.cs b/OpenTween/SocialProtocol/Twitter/TwitterV1Query.cs
new file mode 100644 (file)
index 0000000..14536b1
--- /dev/null
@@ -0,0 +1,77 @@
+// OpenTween - Client of Twitter
+// Copyright (c) 2007-2011 kiri_feather (@kiri_feather) <kiri.feather@gmail.com>
+//           (c) 2008-2011 Moz (@syo68k)
+//           (c) 2008-2011 takeshik (@takeshik) <http://www.takeshik.org/>
+//           (c) 2010-2011 anis774 (@anis774) <http://d.hatena.ne.jp/anis774/>
+//           (c) 2010-2011 fantasticswallow (@f_swallow) <http://twitter.com/f_swallow>
+//           (c) 2011      Egtra (@egtra) <http://dev.activebasic.com/egtra/>
+//           (c) 2013      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.
+
+#nullable enable
+
+using System.Linq;
+using System.Threading.Tasks;
+using OpenTween.Models;
+
+namespace OpenTween.SocialProtocol.Twitter
+{
+    public class TwitterV1Query : ISocialProtocolQuery
+    {
+        private readonly TwitterAccount account;
+
+        public TwitterV1Query(TwitterAccount account)
+        {
+            this.account = account;
+        }
+
+        public async Task<TimelineResponse> GetHomeTimeline(int count, IQueryCursor? cursor, bool firstLoad)
+        {
+            this.account.Legacy.CheckAccountState();
+
+            TwitterStatusId? maxId = null, sinceId = null;
+
+            if (cursor is QueryCursor<TwitterStatusId> statusIdCursor)
+            {
+                if (statusIdCursor.Type == CursorType.Top)
+                    sinceId = statusIdCursor.Value;
+                else if (statusIdCursor.Type == CursorType.Bottom)
+                    maxId = statusIdCursor.Value;
+            }
+
+            var statuses = await this.account.Legacy.Api.StatusesHomeTimeline(count, maxId, sinceId)
+                .ConfigureAwait(false);
+
+            IQueryCursor? cursorTop = null, cursorBottom = null;
+
+            if (statuses.Length > 0)
+            {
+                var (min, max) = statuses.Select(x => new TwitterStatusId(x.IdStr)).MinMax();
+                cursorTop = new QueryCursor<TwitterStatusId>(CursorType.Top, max);
+                cursorBottom = new QueryCursor<TwitterStatusId>(CursorType.Bottom, min);
+            }
+
+            var posts = this.account.Legacy.CreatePostsFromJson(statuses, firstLoad);
+            posts = this.account.Legacy.FilterNoRetweetUserPosts(posts);
+
+            return new(posts, cursorTop, cursorBottom);
+        }
+    }
+}
index b1e424e..f8ce7ad 100644 (file)
@@ -623,57 +623,6 @@ namespace OpenTween
             return Math.Min(count, GetMaxApiResultCount(type));
         }
 
-        public async Task<TimelineResponse> GetHomeTimelineApi(int count, IQueryCursor? cursor, bool firstLoad)
-        {
-            this.CheckAccountState();
-
-            TwitterStatus[] statuses;
-            IQueryCursor? cursorTop = null, cursorBottom = null;
-
-            if (this.Api.AuthType == APIAuthType.TwitterComCookie)
-            {
-                var request = new HomeLatestTimelineRequest
-                {
-                    Count = count,
-                    Cursor = cursor?.As<TwitterGraphqlCursor>(),
-                };
-                var response = await request.Send(this.Api.Connection)
-                    .ConfigureAwait(false);
-
-                statuses = response.ToTwitterStatuses();
-
-                cursorTop = response.CursorTop;
-                cursorBottom = response.CursorBottom;
-            }
-            else
-            {
-                TwitterStatusId? maxId = null, sinceId = null;
-
-                if (cursor is QueryCursor<TwitterStatusId> statusIdCursor)
-                {
-                    if (statusIdCursor.Type == CursorType.Top)
-                        sinceId = statusIdCursor.Value;
-                    else if (statusIdCursor.Type == CursorType.Bottom)
-                        maxId = statusIdCursor.Value;
-                }
-
-                statuses = await this.Api.StatusesHomeTimeline(count, maxId, sinceId)
-                    .ConfigureAwait(false);
-
-                if (statuses.Length > 0)
-                {
-                    var (min, max) = statuses.Select(x => new TwitterStatusId(x.IdStr)).MinMax();
-                    cursorTop = new QueryCursor<TwitterStatusId>(CursorType.Top, max);
-                    cursorBottom = new QueryCursor<TwitterStatusId>(CursorType.Bottom, min);
-                }
-            }
-
-            var posts = this.CreatePostsFromJson(statuses, firstLoad);
-            posts = this.FilterNoRetweetUserPosts(posts);
-
-            return new(posts, cursorTop, cursorBottom);
-        }
-
         public async Task GetMentionsTimelineApi(MentionsTabModel tab, bool more, bool firstLoad)
         {
             this.CheckAccountState();
@@ -815,7 +764,7 @@ namespace OpenTween
             return post;
         }
 
-        private PostClass[] CreatePostsFromJson(TwitterStatus[] statuses, bool firstLoad)
+        internal PostClass[] CreatePostsFromJson(TwitterStatus[] statuses, bool firstLoad)
         {
             var posts = statuses.Select(x => this.CreatePostsFromStatusData(x, firstLoad)).ToArray();
 
@@ -824,7 +773,7 @@ namespace OpenTween
             return posts;
         }
 
-        private PostClass[] FilterNoRetweetUserPosts(PostClass[] posts)
+        internal PostClass[] FilterNoRetweetUserPosts(PostClass[] posts)
             => posts.Where(x => x.RetweetedByUserId == null || !this.Api.AccountState.NoRetweetUserIds.Contains(x.RetweetedByUserId.Value)).ToArray();
 
         public async Task GetListStatus(ListTimelineTabModel tab, bool more, bool firstLoad)
@@ -1445,7 +1394,7 @@ namespace OpenTween
         public string[] GetHashList()
             => this.postFactory.GetReceivedHashtags();
 
-        private void CheckAccountState()
+        internal void CheckAccountState()
         {
             if (Twitter.AccountState != MyCommon.ACCOUNT_STATE.Valid)
                 throw new WebApiException("Auth error. Check your account");