From c95b1acd65eac71bd783cc9bbf95813b042e8ca6 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Thu, 9 May 2024 00:00:21 +0900 Subject: [PATCH] =?utf8?q?PostFavAdd=E3=83=A1=E3=82=BD=E3=83=83=E3=83=89?= =?utf8?q?=E3=82=92ISocialProtocolMutation=E3=81=AB=E7=A7=BB=E5=8B=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../SocialProtocol/Twitter/TwitterAccountTest.cs | 41 ++++++++++++++ OpenTween/SocialProtocol/ISocialAccount.cs | 2 + .../SocialProtocol/ISocialProtocolMutation.cs | 33 +++++++++++ OpenTween/SocialProtocol/Twitter/TwitterAccount.cs | 13 +++++ .../Twitter/TwitterGraphqlMutation.cs | 58 +++++++++++++++++++ .../SocialProtocol/Twitter/TwitterV1Mutation.cs | 66 ++++++++++++++++++++++ OpenTween/Tween.cs | 5 +- OpenTween/Twitter.cs | 28 --------- 8 files changed, 216 insertions(+), 30 deletions(-) create mode 100644 OpenTween/SocialProtocol/ISocialProtocolMutation.cs create mode 100644 OpenTween/SocialProtocol/Twitter/TwitterGraphqlMutation.cs create mode 100644 OpenTween/SocialProtocol/Twitter/TwitterV1Mutation.cs diff --git a/OpenTween.Tests/SocialProtocol/Twitter/TwitterAccountTest.cs b/OpenTween.Tests/SocialProtocol/Twitter/TwitterAccountTest.cs index 02922b38..8df1275e 100644 --- a/OpenTween.Tests/SocialProtocol/Twitter/TwitterAccountTest.cs +++ b/OpenTween.Tests/SocialProtocol/Twitter/TwitterAccountTest.cs @@ -122,5 +122,46 @@ namespace OpenTween.SocialProtocol.Twitter Assert.IsType(account.Query); } + + [Fact] + public void Mutation_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(account.Mutation); + } + + [Fact] + public void Mutation_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(account.Mutation); + } } } diff --git a/OpenTween/SocialProtocol/ISocialAccount.cs b/OpenTween/SocialProtocol/ISocialAccount.cs index 6aa0b8cb..a5701b86 100644 --- a/OpenTween/SocialProtocol/ISocialAccount.cs +++ b/OpenTween/SocialProtocol/ISocialAccount.cs @@ -38,6 +38,8 @@ namespace OpenTween.SocialProtocol public ISocialProtocolQuery Query { get; } + public ISocialProtocolMutation Mutation { get; } + public bool IsDisposed { get; } public void Initialize(UserAccount accountSettings, SettingCommon settingCommon); diff --git a/OpenTween/SocialProtocol/ISocialProtocolMutation.cs b/OpenTween/SocialProtocol/ISocialProtocolMutation.cs new file mode 100644 index 00000000..efe5ea69 --- /dev/null +++ b/OpenTween/SocialProtocol/ISocialProtocolMutation.cs @@ -0,0 +1,33 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2024 kim_upsilon (@kim_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 , 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 ISocialProtocolMutation + { + public Task FavoritePost(PostId postId); + } +} diff --git a/OpenTween/SocialProtocol/Twitter/TwitterAccount.cs b/OpenTween/SocialProtocol/Twitter/TwitterAccount.cs index 6ae5e5d5..6de15b79 100644 --- a/OpenTween/SocialProtocol/Twitter/TwitterAccount.cs +++ b/OpenTween/SocialProtocol/Twitter/TwitterAccount.cs @@ -35,6 +35,8 @@ namespace OpenTween.SocialProtocol.Twitter public ISocialProtocolQuery Query { get; private set; } + public ISocialProtocolMutation Mutation { get; private set; } + public bool IsDisposed { get; private set; } public TwitterAccountState AccountState { get; private set; } = new(); @@ -58,6 +60,7 @@ namespace OpenTween.SocialProtocol.Twitter { this.UniqueKey = uniqueKey; this.Query = this.CreateQueryInstance(APIAuthType.None); + this.Mutation = this.CreateMutationInstance(APIAuthType.None); } public void Initialize(UserAccount accountSettings, SettingCommon settingCommon) @@ -67,6 +70,7 @@ namespace OpenTween.SocialProtocol.Twitter var credential = accountSettings.GetTwitterCredential(); this.AccountState = new TwitterAccountState(accountSettings.UserId, accountSettings.Username); this.Query = this.CreateQueryInstance(credential.AuthType); + this.Mutation = this.CreateMutationInstance(credential.AuthType); this.twLegacy.Initialize(credential, this.AccountState); this.twLegacy.RestrictFavCheck = settingCommon.RestrictFavCheck; @@ -89,5 +93,14 @@ namespace OpenTween.SocialProtocol.Twitter _ => new TwitterV1Query(this), }; } + + private ISocialProtocolMutation CreateMutationInstance(APIAuthType authType) + { + return authType switch + { + APIAuthType.TwitterComCookie => new TwitterGraphqlMutation(this), + _ => new TwitterV1Mutation(this), + }; + } } } diff --git a/OpenTween/SocialProtocol/Twitter/TwitterGraphqlMutation.cs b/OpenTween/SocialProtocol/Twitter/TwitterGraphqlMutation.cs new file mode 100644 index 00000000..f87028f8 --- /dev/null +++ b/OpenTween/SocialProtocol/Twitter/TwitterGraphqlMutation.cs @@ -0,0 +1,58 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2024 kim_upsilon (@kim_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 , 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 TwitterGraphqlMutation : ISocialProtocolMutation + { + private readonly TwitterAccount account; + + public TwitterGraphqlMutation(TwitterAccount account) + { + this.account = account; + } + + public async Task FavoritePost(PostId postId) + { + var statusId = this.AssertTwitterStatusId(postId); + var request = new FavoriteTweetRequest + { + TweetId = statusId, + }; + + await request.Send(this.account.Connection) + .ConfigureAwait(false); + } + + private TwitterStatusId AssertTwitterStatusId(PostId postId) + { + return postId is TwitterStatusId statusId + ? statusId + : throw new WebApiException($"Not supported type: {postId.GetType()}"); + } + } +} diff --git a/OpenTween/SocialProtocol/Twitter/TwitterV1Mutation.cs b/OpenTween/SocialProtocol/Twitter/TwitterV1Mutation.cs new file mode 100644 index 00000000..4a5d864e --- /dev/null +++ b/OpenTween/SocialProtocol/Twitter/TwitterV1Mutation.cs @@ -0,0 +1,66 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2024 kim_upsilon (@kim_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 , 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.Api; +using OpenTween.Api.DataModel; +using OpenTween.Connection; +using OpenTween.Models; + +namespace OpenTween.SocialProtocol.Twitter +{ + public class TwitterV1Mutation : ISocialProtocolMutation + { + private readonly TwitterAccount account; + + public TwitterV1Mutation(TwitterAccount account) + { + this.account = account; + } + + public async Task FavoritePost(PostId postId) + { + var statusId = this.AssertTwitterStatusId(postId); + + try + { + await this.account.Legacy.Api.FavoritesCreate(statusId) + .IgnoreResponse() + .ConfigureAwait(false); + } + catch (TwitterApiException ex) + when (ex.Errors.All(x => x.Code == TwitterErrorCode.AlreadyFavorited)) + { + // エラーコード 139 のみの場合は成功と見なす + } + } + + private TwitterStatusId AssertTwitterStatusId(PostId postId) + { + return postId is TwitterStatusId statusId + ? statusId + : throw new WebApiException($"Not supported type: {postId.GetType()}"); + } + } +} diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 68a94083..63ac96b4 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -1381,13 +1381,14 @@ namespace OpenTween try { - var twitterStatusId = (post.RetweetedId ?? post.StatusId).ToTwitterStatusId(); + var originalPostId = post.RetweetedId ?? post.StatusId; - await this.tw.PostFavAdd(twitterStatusId) + await this.CurrentTabAccount.Mutation.FavoritePost(originalPostId) .ConfigureAwait(false); if (this.settings.Common.RestrictFavCheck) { + var twitterStatusId = originalPostId.ToTwitterStatusId(); var status = await this.tw.Api.StatusesShow(twitterStatusId) .ConfigureAwait(false); diff --git a/OpenTween/Twitter.cs b/OpenTween/Twitter.cs index f8ce7ad5..9b012706 100644 --- a/OpenTween/Twitter.cs +++ b/OpenTween/Twitter.cs @@ -474,34 +474,6 @@ namespace OpenTween } } - public async Task PostFavAdd(TwitterStatusId statusId) - { - if (this.Api.AuthType == APIAuthType.TwitterComCookie) - { - var request = new FavoriteTweetRequest - { - TweetId = statusId, - }; - - await request.Send(this.Api.Connection) - .ConfigureAwait(false); - } - else - { - try - { - await this.Api.FavoritesCreate(statusId) - .IgnoreResponse() - .ConfigureAwait(false); - } - catch (TwitterApiException ex) - when (ex.Errors.All(x => x.Code == TwitterErrorCode.AlreadyFavorited)) - { - // エラーコード 139 のみの場合は成功と見なす - } - } - } - public async Task PostFavRemove(TwitterStatusId statusId) { if (this.Api.AuthType == APIAuthType.TwitterComCookie) -- 2.11.0