From 6c305bc138618efb906579be0d27448edef61368 Mon Sep 17 00:00:00 2001 From: Storm Dragon Date: Fri, 25 Jul 2025 23:51:09 -0400 Subject: [PATCH] Boosted posts should now be well handled instead of being blank. --- ttyverse.pl | 102 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 89 insertions(+), 13 deletions(-) diff --git a/ttyverse.pl b/ttyverse.pl index ce7036d..45c8d24 100755 --- a/ttyverse.pl +++ b/ttyverse.pl @@ -4314,7 +4314,7 @@ EOF } elsif ($rout =~ /^ki ([^\s]+) /) { my $key = $1; my $module; - sysread(STDIN, $module, 1024); + read(STDIN, $module, 1024); $module =~ s/\s+$//; $module = pack("H*", $module); print $stdout "-- fetch for module $module key $key\n" @@ -4326,7 +4326,7 @@ EOF } elsif ($rout =~ /^kn ([^\s]+) /) { my $key = $1; my $module; - sysread(STDIN, $module, 1024); + read(STDIN, $module, 1024); $module =~ s/\s+$//; $module = pack("H*", $module); print $stdout "-- nulled module $module key $key\n" @@ -4337,10 +4337,10 @@ EOF my $key = $1; my $value; my $module; - sysread(STDIN, $module, 1024); + read(STDIN, $module, 1024); $module =~ s/\s+$//; $module = pack("H*", $module); - sysread(STDIN, $value, 1024); + read(STDIN, $value, 1024); $value =~ s/\s+$//; print $stdout "-- set module $module key $key = $value\n" @@ -4362,7 +4362,7 @@ EOF if ($comm eq '?') { print P substr("${$key}$space_pad", 0, 1024); } else { - sysread(STDIN, $value, 1024); + read(STDIN, $value, 1024); $value =~ s/\s+$//; $interactive = ($comm eq '+') ? 0 : 1; if ($key eq 'tquery') { @@ -5158,6 +5158,12 @@ sub tdisplay { # used by both synchronous /again and asynchronous refreshes my $sn = $j->{'user'}->{'screen_name'}; next if (!length($sn)); $sn = lc(&descape($sn)); + + # Debug: Check what data is in the processing loop for boost posts + if (exists($j->{'boost_attribution'}) && $j->{'boost_attribution'}) { + my $text_debug = $j->{'text'} || ''; + print $stdout "-- DEBUG: Processing loop received boost - user: '$sn', text: '$text_debug', boost_attribution: '" . $j->{'boost_attribution'} . "'\n" if ($verbose); + } # # implement filter stages: @@ -5659,6 +5665,17 @@ sub standardtweet { my $sn = &descape($ref->{'user'}->{'screen_name'}); my $tweet = &descape($ref->{'text'}); + + # Debug boost display + if (exists($ref->{'boost_attribution'}) && $ref->{'boost_attribution'}) { + print $stdout "-- DEBUG: standardtweet - user: '$sn', text: '$tweet', boost_attribution: '" . $ref->{'boost_attribution'} . "'\n" if ($verbose); + } + + # Add boost attribution if this is a boosted post + if (exists($ref->{'boost_attribution'}) && $ref->{'boost_attribution'}) { + my $booster = &descape($ref->{'boost_attribution'}); + $tweet = "[boosted $booster] $tweet"; + } my $colour; my $g; my $h; @@ -6108,6 +6125,11 @@ sub defaulthandle { my $dclass = ($verbose) ? "{$class,$tweet_ref->{'id_str'}} " : ''; my $sn = &descape($tweet_ref->{'user'}->{'screen_name'}); my $tweet = &descape($tweet_ref->{'text'}); + + # Debug: Check what data defaulthandle receives for boost posts + if (exists($tweet_ref->{'boost_attribution'}) && $tweet_ref->{'boost_attribution'}) { + print $stdout "-- DEBUG: defaulthandle received boost - user: '$sn', text: '$tweet', boost_attribution: '" . $tweet_ref->{'boost_attribution'} . "'\n" if ($verbose); + } my $stweet = &standardtweet($tweet_ref); my $menu_select = $tweet_ref->{'menu_select'}; @@ -7566,16 +7588,52 @@ sub normalizejson { # normalize newRTs # if we get newRTs with -nonewrts, oh well + my $boost_content = ''; + my $boost_attribution = ''; + my $boost_user = undef; + if (!$nonewrts && ($rt = $i->{'retweeted_status'})) { - # reconstruct the RT in a "canonical" format + # reconstruct the boost in fediverse format: [boosted ] content # without truncation, but detco it first $rt = &destroy_all_tco($rt); $i->{'retweeted_status'} = $rt; - $i->{'text'} = - "RT \@$rt->{'user'}->{'screen_name'}" . ': ' . $rt->{'text'}; + + # Get original author and content + my $original_author = $rt->{'user'}->{'screen_name'} || 'unknown_user'; + my $content = $rt->{'text'} || ''; + + # Get booster (who shared this) + my $booster = $i->{'user'}->{'screen_name'} || 'unknown_booster'; + if (exists($i->{'user'}->{'acct'})) { + $booster = $i->{'user'}->{'acct'}; + } + + print $stdout "-- DEBUG: Boost - original: '$original_author', booster: '$booster', content: '$content'\n" if ($verbose); + + # Store boost data to apply after destroy_all_tco + $boost_content = $content; + my $original_acct = $rt->{'user'}->{'acct'} || $rt->{'user'}->{'screen_name'} || $original_author; + $boost_attribution = $original_acct; + + # Set booster as the main user (who performed the boost action) + $boost_user = { + 'screen_name' => $booster, + 'acct' => $booster + }; } - return &destroy_all_tco($i); + # Apply destroy_all_tco first + $i = &destroy_all_tco($i); + + # Now apply boost data after destroy_all_tco processing + if ($boost_content) { + $i->{'text'} = $boost_content; + $i->{'boost_attribution'} = $boost_attribution; + $i->{'user'} = $boost_user; + print $stdout "-- DEBUG: Final boost data applied - text: '$boost_content', attribution: '$boost_attribution'\n" if ($verbose); + } + + return $i; } # process the JSON data ... simplemindedly, because I just write utter crap, @@ -7743,7 +7801,7 @@ sub map_mastodon_fields { # Handle single status objects if (ref($json_ref) eq 'HASH' && exists($json_ref->{'content'})) { - $json_ref = &map_single_status($json_ref); + $json_ref = &map_single_status($json_ref, 0); } # Handle user/account objects (verify_credentials, etc.) elsif (ref($json_ref) eq 'HASH' && exists($json_ref->{'username'})) { @@ -7752,7 +7810,7 @@ sub map_mastodon_fields { # Handle arrays of statuses (timelines) elsif (ref($json_ref) eq 'ARRAY') { for my $i (0..$#{$json_ref}) { - $json_ref->[$i] = &map_single_status($json_ref->[$i]) + $json_ref->[$i] = &map_single_status($json_ref->[$i], 0) if (ref($json_ref->[$i]) eq 'HASH'); } } @@ -7762,8 +7820,25 @@ sub map_mastodon_fields { sub map_single_status { my $status = shift; + my $recursion_depth = shift || 0; return $status unless (ref($status) eq 'HASH'); + # Prevent infinite recursion - limit depth to 1 level + return $status if ($recursion_depth > 1); + + # Skip re-processing if this is already a processed boost post + if (exists($status->{'boost_attribution'}) && $status->{'boost_attribution'}) { + print $stdout "-- DEBUG: Skipping re-processing of already processed boost post\n" if ($verbose); + return $status; + } + + # Debug: Check if this is a boost + if (exists($status->{'reblog'}) && $status->{'reblog'}) { + print $stdout "-- DEBUG: Found boost - original account: " . ($status->{'account'}->{'acct'} || 'unknown') . "\n" if ($verbose); + print $stdout "-- DEBUG: Reblog content present: " . (exists($status->{'reblog'}->{'content'}) ? 'yes' : 'no') . "\n" if ($verbose); + print $stdout "-- DEBUG: Reblog account present: " . (exists($status->{'reblog'}->{'account'}) ? 'yes' : 'no') . "\n" if ($verbose); + } + # Core Mastodon → Twitter field mappings if (exists($status->{'content'})) { $status->{'text'} = &html_to_text($status->{'content'}); @@ -7783,9 +7858,10 @@ sub map_single_status { # Keep acct field for full handle (username@domain.com) } - # Recursively map reblogged status + # Recursively map reblogged status - with depth limit to prevent infinite recursion if (exists($status->{'retweeted_status'})) { - $status->{'retweeted_status'} = &map_single_status($status->{'retweeted_status'}); + print $stdout "-- DEBUG: Processing reblogged status recursively (depth: $recursion_depth)\n" if ($verbose); + $status->{'retweeted_status'} = &map_single_status($status->{'retweeted_status'}, $recursion_depth + 1); } return $status;