Create fake users for tombstones whose users can't be inferred

This commit is contained in:
Alessio 2023-06-19 21:25:20 -03:00
parent 0dd759ce54
commit 3340fc3da3
3 changed files with 39 additions and 7 deletions

View File

@ -454,10 +454,10 @@ func (e APIV2Entry) ToTweetTrove() TweetTrove {
} else if e.Content.EntryType == "TimelineTimelineItem" { } else if e.Content.EntryType == "TimelineTimelineItem" {
ret, err := e.Content.ItemContent.TweetResults.ToTweetTrove() ret, err := e.Content.ItemContent.TweetResults.ToTweetTrove()
// Handle tombstones in parent reply thread
if errors.Is(err, ErrorIsTombstone) { if errors.Is(err, ErrorIsTombstone) {
// Handle tombstones ret = NewTweetTrove() // clear the result just in case there is a TweetID(0) in it
ret = NewTweetTrove() // clear the result just in case tombstoned_tweet := APITweet{}
tombstoned_tweet := e.Content.ItemContent.TweetResults.Result.Legacy.APITweet // Will be empty to start
// Capture the tombstone text // Capture the tombstone text
var is_ok bool var is_ok bool
@ -480,6 +480,8 @@ func (e APIV2Entry) ToTweetTrove() TweetTrove {
panic(err) panic(err)
} }
ret.Tweets[parsed_tombstone_tweet.ID] = parsed_tombstone_tweet ret.Tweets[parsed_tombstone_tweet.ID] = parsed_tombstone_tweet
} else if err != nil {
panic(err)
} }
return ret return ret
} }
@ -626,11 +628,14 @@ func (api_response APIV2Response) ToTweetTrove() (TweetTrove, error) {
panic(fmt.Sprintf("Tombstoned tweet has no ID (should be %d)", tweet.InReplyToID)) panic(fmt.Sprintf("Tombstoned tweet has no ID (should be %d)", tweet.InReplyToID))
} }
// Fill out the replied tweet's UserID using this tweet's "in_reply_to_user_id".
// If this tweet doesn't have it (i.e., this tweet is also a tombstone), create a fake user instead, and add it to the tweet trove.
if replied_tweet.UserID == 0 { if replied_tweet.UserID == 0 {
replied_tweet.UserID = tweet.in_reply_to_user_id replied_tweet.UserID = tweet.in_reply_to_user_id
if replied_tweet.UserID == 0 { // Still?? if replied_tweet.UserID == 0 {
log.Warn(fmt.Sprintf("Still couldn't find user for replied tweet %d", tweet.InReplyToID)) fake_user := GetUnknownUser()
continue ret.Users[fake_user.ID] = fake_user
replied_tweet.UserID = fake_user.ID
} }
} // replied_tweet.UserID should now be a real UserID } // replied_tweet.UserID should now be a real UserID

View File

@ -601,12 +601,21 @@ func TestAPIV2ConversationThreadWithTombstones(t *testing.T) {
assert.True(is_ok) assert.True(is_ok)
assert.True(t1.IsStub) assert.True(t1.IsStub)
assert.Equal(TweetID(0), t1.InReplyToID) assert.Equal(TweetID(0), t1.InReplyToID)
// TODO: assert associated user is fake assert.NotEqual(UserID(0), t1.UserID)
t1_user, is_ok := trove.Users[t1.UserID]
assert.True(is_ok)
assert.True(t1_user.IsIdFake)
assert.Equal(UserHandle("<UNKNOWN USER>"), t1_user.Handle)
t2, is_ok := trove.Tweets[1454521424144654344] t2, is_ok := trove.Tweets[1454521424144654344]
assert.True(is_ok) assert.True(is_ok)
assert.True(t2.IsStub) assert.True(t2.IsStub)
assert.Equal(TweetID(1454515503242829830), t2.InReplyToID) assert.Equal(TweetID(1454515503242829830), t2.InReplyToID)
assert.NotEqual(UserID(0), t2.UserID)
t2_user, is_ok := trove.Users[t2.UserID]
assert.True(is_ok)
assert.True(t2_user.IsIdFake)
assert.Equal(UserHandle("<UNKNOWN USER>"), t2_user.Handle)
t3, is_ok := trove.Tweets[1454522147750260742] t3, is_ok := trove.Tweets[1454522147750260742]
assert.True(is_ok) assert.True(is_ok)

View File

@ -84,6 +84,24 @@ Joined %s
return ret return ret
} }
func GetUnknownUser() User {
return User{
ID: UserID(0x4000000000000000), // 2^62
DisplayName: "<Unknown User>",
Handle: UserHandle("<UNKNOWN USER>"),
Bio: "<blank>",
FollowersCount: 0,
FollowingCount: 0,
Location: "<blank>",
Website: "<blank>",
JoinDate: TimestampFromUnix(0),
IsVerified: false,
IsPrivate: false,
IsNeedingFakeID: false,
IsIdFake: true,
}
}
/** /**
* Unknown Users with handles are only created by direct GetUser calls (either `twitter fetch_user` * Unknown Users with handles are only created by direct GetUser calls (either `twitter fetch_user`
* subcommand or as part of tombstone user fetching.) * subcommand or as part of tombstone user fetching.)