Skip to content

Commit

Permalink
Merge pull request #326 from opentween/account-state
Browse files Browse the repository at this point in the history
ユーザー名や発言数などアカウントの可変な情報をTwitterAccountStateクラスに分離
  • Loading branch information
upsilon authored May 6, 2024
2 parents 0a6410e + eb7dd7f commit 46d6252
Show file tree
Hide file tree
Showing 8 changed files with 167 additions and 54 deletions.
20 changes: 8 additions & 12 deletions OpenTween.Tests/Api/TwitterApiTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
using Moq;
using OpenTween.Api.DataModel;
using OpenTween.Connection;
using OpenTween.SocialProtocol.Twitter;
using Xunit;

namespace OpenTween.Api
Expand All @@ -57,26 +58,24 @@ public void Initialize_Test()
Assert.IsType<TwitterCredentialNone>(apiConnection.Credential);

var credential = new TwitterCredentialOAuth1(TwitterAppToken.GetDefault(), "*** AccessToken ***", "*** AccessSecret ***");
twitterApi.Initialize(credential, userId: 100L, screenName: "hogehoge");
var accountState = new TwitterAccountState(100L, "hogehoge");
twitterApi.Initialize(credential, accountState);

apiConnection = Assert.IsType<TwitterApiConnection>(twitterApi.Connection);
Assert.Same(credential, apiConnection.Credential);

Assert.Equal(100L, twitterApi.CurrentUserId);
Assert.Equal("hogehoge", twitterApi.CurrentScreenName);
Assert.Same(accountState, twitterApi.AccountState);

// 複数回 Initialize を実行した場合は新たに TwitterApiConnection が生成される
var credential2 = new TwitterCredentialOAuth1(TwitterAppToken.GetDefault(), "*** AccessToken2 ***", "*** AccessSecret2 ***");
twitterApi.Initialize(credential2, userId: 200L, screenName: "foobar");
var accountState2 = new TwitterAccountState(200L, "foobar");
twitterApi.Initialize(credential2, accountState2);

var oldApiConnection = apiConnection;
Assert.True(oldApiConnection.IsDisposed);

apiConnection = Assert.IsType<TwitterApiConnection>(twitterApi.Connection);
Assert.Same(credential2, apiConnection.Credential);

Assert.Equal(200L, twitterApi.CurrentUserId);
Assert.Equal("foobar", twitterApi.CurrentScreenName);
Assert.Same(accountState2, twitterApi.AccountState);
}

private Mock<IApiConnection> CreateApiConnectionMock<T>(Action<T> verifyRequest)
Expand Down Expand Up @@ -1173,10 +1172,7 @@ public async Task AccountVerifyCredentials_Test()
using var twitterApi = new TwitterApi();
twitterApi.ApiConnection = mock.Object;

await twitterApi.AccountVerifyCredentials();

Assert.Equal(100L, twitterApi.CurrentUserId);
Assert.Equal("opentween", twitterApi.CurrentScreenName);
var user = await twitterApi.AccountVerifyCredentials();

mock.VerifyAll();
}
Expand Down
52 changes: 52 additions & 0 deletions OpenTween.Tests/SocialProtocol/Twitter/TwitterAccountStateTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// 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.

using OpenTween.Api.DataModel;
using Xunit;

namespace OpenTween.SocialProtocol.Twitter
{
public class TwitterAccountStateTest
{
[Fact]
public void UpdateFromUser_Test()
{
var accountState = new TwitterAccountState();

var twitterUser = new TwitterUser
{
Id = 514241801L,
IdStr = "514241801",
ScreenName = "OpenTween",
StatusesCount = 31,
FriendsCount = 1,
FollowersCount = 302,
};
accountState.UpdateFromUser(twitterUser);

Assert.Equal(514241801L, accountState.UserId);
Assert.Equal("OpenTween", accountState.UserName);
Assert.Equal(31, accountState.StatusesCount);
Assert.Equal(1, accountState.FriendsCount);
Assert.Equal(302, accountState.FollowersCount);
}
}
}
17 changes: 9 additions & 8 deletions OpenTween/Api/TwitterApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,34 +32,38 @@
using OpenTween.Api.DataModel;
using OpenTween.Connection;
using OpenTween.Models;
using OpenTween.SocialProtocol.Twitter;

namespace OpenTween.Api
{
public sealed class TwitterApi : IDisposable
{
public long CurrentUserId { get; private set; }
public long CurrentUserId
=> this.AccountState.UserId;

public string CurrentScreenName { get; private set; } = "";
public string CurrentScreenName
=> this.AccountState.UserName;

public IApiConnection Connection => this.ApiConnection;

internal IApiConnection ApiConnection;

public APIAuthType AuthType { get; private set; } = APIAuthType.None;

public TwitterAccountState AccountState { get; private set; } = new();

public TwitterApi()
=> this.ApiConnection = new TwitterApiConnection(new TwitterCredentialNone());

public void Initialize(ITwitterCredential credential, long userId, string screenName)
public void Initialize(ITwitterCredential credential, TwitterAccountState accountState)
{
this.AuthType = credential.AuthType;

var newInstance = new TwitterApiConnection(credential);
var oldInstance = Interlocked.Exchange(ref this.ApiConnection, newInstance);
oldInstance?.Dispose();

this.CurrentUserId = userId;
this.CurrentScreenName = screenName;
this.AccountState = accountState;
}

public async Task<TwitterStatus[]> StatusesHomeTimeline(int? count = null, TwitterStatusId? maxId = null, TwitterStatusId? sinceId = null)
Expand Down Expand Up @@ -978,9 +982,6 @@ public async Task<TwitterUser> AccountVerifyCredentials()
var user = await response.ReadAsJson<TwitterUser>()
.ConfigureAwait(false);

this.CurrentUserId = user.Id;
this.CurrentScreenName = user.ScreenName;

return user;
}

Expand Down
2 changes: 1 addition & 1 deletion OpenTween/AppendSettingDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ private async void AddAccountButton_Click(object sender, EventArgs e)
};

using var twitterApi = new TwitterApi();
twitterApi.Initialize(new TwitterCredentialCookie(appToken), 0L, "");
twitterApi.Initialize(new TwitterCredentialCookie(appToken), new());
var twitterUser = await twitterApi.AccountVerifyCredentials();
newAccount.UserId = twitterUser.Id;
newAccount.Username = twitterUser.ScreenName;
Expand Down
9 changes: 6 additions & 3 deletions OpenTween/SocialProtocol/Twitter/TwitterAccount.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,16 @@ public class TwitterAccount : ISocialAccount

public bool IsDisposed { get; private set; }

public TwitterAccountState AccountState { get; private set; } = new();

public OpenTween.Twitter Legacy
=> this.twLegacy;

public long UserId
=> this.Legacy.UserId;
=> this.AccountState.UserId;

public string UserName
=> this.Legacy.Username;
=> this.AccountState.UserName;

public APIAuthType AuthType
=> this.Legacy.Api.AuthType;
Expand All @@ -58,7 +60,8 @@ public void Initialize(UserAccount accountSettings, SettingCommon settingCommon)
Debug.Assert(accountSettings.UniqueKey == this.UniqueKey, "UniqueKey must be same as current value.");

var credential = accountSettings.GetTwitterCredential();
this.twLegacy.Initialize(credential, accountSettings.Username, accountSettings.UserId);
this.AccountState = new TwitterAccountState(accountSettings.UserId, accountSettings.Username);
this.twLegacy.Initialize(credential, this.AccountState);
this.twLegacy.RestrictFavCheck = settingCommon.RestrictFavCheck;
}

Expand Down
66 changes: 66 additions & 0 deletions OpenTween/SocialProtocol/Twitter/TwitterAccountState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// 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.Collections.Generic;
using OpenTween.Api.DataModel;

namespace OpenTween.SocialProtocol.Twitter
{
public class TwitterAccountState
{
public long UserId { get; private set; }

public string UserName { get; private set; }

public int? FollowersCount { get; private set; }

public int? FriendsCount { get; private set; }

public int? StatusesCount { get; private set; }

public ISet<long> FollowerIds { get; set; } = new HashSet<long>();

public ISet<long> NoRetweetUserIds { get; set; } = new HashSet<long>();

public TwitterAccountState()
: this(0L, "")
{
}

public TwitterAccountState(long userId, string userName)
{
this.UserId = userId;
this.UserName = userName;
}

/// <summary>ユーザー情報を更新します</summary>
public void UpdateFromUser(TwitterUser self)
{
this.UserId = self.Id;
this.UserName = self.ScreenName;
this.FollowersCount = self.FollowersCount;
this.FriendsCount = self.FriendsCount;
this.StatusesCount = self.StatusesCount;
}
}
}
10 changes: 8 additions & 2 deletions OpenTween/Tween.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6774,8 +6774,14 @@ private void SetMainWindowTitle()
ttl.AppendFormat(Properties.Resources.SetMainWindowTitleText4, ur, al);
break;
case MyCommon.DispTitleEnum.OwnStatus:
if (followers == 0 && this.tw.FollowersCount > 0) followers = this.tw.FollowersCount;
ttl.AppendFormat(Properties.Resources.OwnStatusTitle, this.tw.StatusesCount, this.tw.FriendsCount, this.tw.FollowersCount, this.tw.FollowersCount - followers);
if (followers == 0 && this.tw.FollowersCount != null) followers = this.tw.FollowersCount.Value;
ttl.AppendFormat(
Properties.Resources.OwnStatusTitle,
this.tw.StatusesCount?.ToString() ?? "-",
this.tw.FriendsCount?.ToString() ?? "-",
this.tw.FollowersCount?.ToString() ?? "-",
this.tw.FollowersCount != null ? this.tw.FollowersCount.Value - followers : "-"
);
break;
}

Expand Down
Loading

0 comments on commit 46d6252

Please sign in to comment.