From bd9b5fa5fbe9a99a8baf111c9479258138f75e9e Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Thu, 20 Jul 2023 01:51:36 +0900 Subject: [PATCH] =?UTF-8?q?SelfThread=E3=81=AE=E3=83=84=E3=82=A4=E3=83=BC?= =?UTF-8?q?=E3=83=88=E3=82=92=E5=8F=96=E5=BE=97=E3=81=A7=E3=81=8D=E3=81=AA?= =?UTF-8?q?=E3=81=84=E4=B8=8D=E5=85=B7=E5=90=88=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: 4b517de2 ("TweetDetailを使用したツイートの取得に対応") --- CHANGELOG.txt | 1 + .../Api/GraphQL/TimelineTweetTest.cs | 13 ++ OpenTween.Tests/OpenTween.Tests.csproj | 3 + .../Responses/TimelineTweet_SelfThread.json | 124 ++++++++++++++++++ OpenTween/Api/GraphQL/TimelineTweet.cs | 2 +- OpenTween/Twitter.cs | 4 +- 6 files changed, 145 insertions(+), 2 deletions(-) create mode 100644 OpenTween.Tests/Resources/Responses/TimelineTweet_SelfThread.json diff --git a/CHANGELOG.txt b/CHANGELOG.txt index a74dac5d3..cf30d6024 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -2,6 +2,7 @@ ==== Unreleased * FIX: Cookie使用時に複数回ツイートを投稿するとDelaying?のエラーが表示される不具合を修正 + * FIX: 自己リプライのスレッドに含まれるツイートを発言一覧で選択するとエラーが発生する不具合を修正 ==== Ver 3.7.0(2023/07/19) * NEW: Cookie使用時のツイート投稿・削除に対応 diff --git a/OpenTween.Tests/Api/GraphQL/TimelineTweetTest.cs b/OpenTween.Tests/Api/GraphQL/TimelineTweetTest.cs index da6720b3a..0d6cb1287 100644 --- a/OpenTween.Tests/Api/GraphQL/TimelineTweetTest.cs +++ b/OpenTween.Tests/Api/GraphQL/TimelineTweetTest.cs @@ -123,5 +123,18 @@ public void ToStatus_WithTwitterPostFactory_TweetWithVisibility_Test() Assert.Equal("1602775353088524288", post.StatusId.Id); Assert.Equal(357750891L, post.UserId); } + + [Fact] + public void ToStatus_WithTwitterPostFactory_SelfThread_Test() + { + var rootElm = this.LoadResponseDocument("TimelineTweet_SelfThread.json"); + var timelineTweet = new TimelineTweet(rootElm); + var status = timelineTweet.ToTwitterStatus(); + var postFactory = new TwitterPostFactory(this.CreateTabInfo()); + var post = postFactory.CreateFromStatus(status, selfUserId: 1L, new HashSet()); + + Assert.Equal("1511751702684499968", post.StatusId.Id); + Assert.Equal(40480664L, post.UserId); + } } } diff --git a/OpenTween.Tests/OpenTween.Tests.csproj b/OpenTween.Tests/OpenTween.Tests.csproj index 950a2a344..3ba9bc30f 100644 --- a/OpenTween.Tests/OpenTween.Tests.csproj +++ b/OpenTween.Tests/OpenTween.Tests.csproj @@ -82,5 +82,8 @@ PreserveNewest + + PreserveNewest + diff --git a/OpenTween.Tests/Resources/Responses/TimelineTweet_SelfThread.json b/OpenTween.Tests/Resources/Responses/TimelineTweet_SelfThread.json new file mode 100644 index 000000000..489d46851 --- /dev/null +++ b/OpenTween.Tests/Resources/Responses/TimelineTweet_SelfThread.json @@ -0,0 +1,124 @@ +{ + "itemType": "TimelineTweet", + "__typename": "TimelineTweet", + "tweet_results": { + "result": { + "__typename": "Tweet", + "rest_id": "1511751702684499968", + "has_birdwatch_notes": false, + "core": { + "user_results": { + "result": { + "__typename": "User", + "id": "VXNlcjo0MDQ4MDY2NA==", + "rest_id": "40480664", + "affiliates_highlighted_label": {}, + "has_graduated_access": true, + "is_blue_verified": false, + "profile_image_shape": "Circle", + "legacy": { + "followed_by": true, + "following": true, + "can_dm": true, + "can_media_tag": true, + "created_at": "Sat May 16 15:20:01 +0000 2009", + "default_profile": false, + "default_profile_image": false, + "description": "OpenTween Project 言い出しっぺ", + "entities": { + "description": { + "urls": [] + }, + "url": { + "urls": [ + { + "display_url": "m.upsilo.net/@upsilon", + "expanded_url": "https://m.upsilo.net/@upsilon", + "url": "https://t.co/vNMmyHHOQD", + "indices": [ + 0, + 23 + ] + } + ] + } + }, + "fast_followers_count": 0, + "favourites_count": 216205, + "followers_count": 1304, + "friends_count": 917, + "has_custom_timelines": false, + "is_translator": false, + "listed_count": 92, + "location": "Funabashi, Chiba, Japan", + "media_count": 1040, + "name": "upsilon", + "normal_followers_count": 1304, + "pinned_tweet_ids_str": [], + "possibly_sensitive": false, + "profile_banner_url": "https://pbs.twimg.com/profile_banners/40480664/1349188016", + "profile_image_url_https": "https://pbs.twimg.com/profile_images/719076434/____normal.png", + "profile_interstitial_type": "", + "screen_name": "kim_upsilon", + "statuses_count": 10096, + "translator_type": "regular", + "url": "https://t.co/vNMmyHHOQD", + "verified": false, + "want_retweets": true, + "withheld_in_countries": [] + } + } + } + }, + "edit_control": { + "edit_tweet_ids": [ + "1511751702684499968" + ], + "editable_until_msecs": "1649266467565", + "is_edit_eligible": true, + "edits_remaining": "5" + }, + "edit_perspective": { + "favorited": false, + "retweeted": false + }, + "is_translatable": true, + "views": { + "state": "Enabled" + }, + "source": "OpenTween (dev)", + "legacy": { + "bookmark_count": 0, + "bookmarked": false, + "created_at": "Wed Apr 06 17:04:27 +0000 2022", + "conversation_id_str": "1511751702684499968", + "display_text_range": [ + 0, + 45 + ], + "entities": { + "user_mentions": [], + "urls": [], + "hashtags": [], + "symbols": [] + }, + "favorite_count": 1, + "favorited": false, + "full_text": "OpenTweenそろそろ次のリリースしたいんだけど今のAPI規制下で出してもねえ、という", + "is_quote_status": false, + "lang": "ja", + "quote_count": 0, + "reply_count": 1, + "retweet_count": 0, + "retweeted": false, + "user_id_str": "40480664", + "id_str": "1511751702684499968" + }, + "quick_promote_eligibility": { + "eligibility": "IneligibleNotProfessional" + } + } + }, + "tweetDisplayType": "SelfThread", + "hasModeratedReplies": false +} diff --git a/OpenTween/Api/GraphQL/TimelineTweet.cs b/OpenTween/Api/GraphQL/TimelineTweet.cs index 77dc06809..9cf3bfffc 100644 --- a/OpenTween/Api/GraphQL/TimelineTweet.cs +++ b/OpenTween/Api/GraphQL/TimelineTweet.cs @@ -156,7 +156,7 @@ private static Exception CreateParseError() public static TimelineTweet[] ExtractTimelineTweets(XElement element) { - return element.XPathSelectElements($"//itemContent[itemType[text()='{TypeName}']][tweetDisplayType[text()='Tweet']]") + return element.XPathSelectElements($"//itemContent[itemType[text()='{TypeName}']][tweetDisplayType[text()='Tweet' or text()='SelfThread']]") .Select(x => new TimelineTweet(x)) .ToArray(); } diff --git a/OpenTween/Twitter.cs b/OpenTween/Twitter.cs index d1e7e763e..b4c2a0cd4 100644 --- a/OpenTween/Twitter.cs +++ b/OpenTween/Twitter.cs @@ -689,7 +689,9 @@ public async Task GetStatusApi(bool read, TwitterStatusId id) FocalTweetId = id, }; var tweets = await request.Send(this.Api.Connection).ConfigureAwait(false); - status = tweets.Select(x => x.ToTwitterStatus()).Where(x => x.IdStr == id.Id).First(); + status = tweets.Select(x => x.ToTwitterStatus()) + .Where(x => x.IdStr == id.Id) + .FirstOrDefault() ?? throw new WebApiException("Empty result set"); } else {