Skip to content

Instantly share code, notes, and snippets.

@eqhmcow
Last active Aug 28, 2022
Embed
What would you like to do?
re-format text from e.g. rainbowstream twitter output
#!/usr/bin/perl
use strict;
use warnings;
$|++;
use Text::Format;
use IO::Select;
use Time::HiRes;
use Getopt::Long;
my $sleep_interval = 2;
my $slow = 0;
GetOptions(
"sleep|s=i" => \$sleep_interval,
"slow" => \$slow,
) or die "Error parsing arguments";
my $s = IO::Select->new(\*STDIN);
my @input;
my $prev_tweet_head;
my @prev_tweet;
my $current_tweet_head;
while (1) {
# read in available tweets
while ($s->can_read(2)) {
my $line = read_unbuffered_line();
last unless defined $line;
push @input, $line;
}
# sleep if nothing to read
unless (@input) {
# print the final tweet we may have buffered
print_tweet($prev_tweet_head, @prev_tweet);
undef $prev_tweet_head;
undef @prev_tweet;
sleep $sleep_interval;
next;
}
# parse tweets
while ($_ = shift(@input)) {
# strip timestamp
s/^.{29}//;
# is this the start of new a tweet?
if (m/^(\x1b\x5b\S+m|\s)+([^@]|.@.)+(\x1b\x5b\S+m|\s)+@\S+(\x1b\x5b\S+m|\s)+(just now|\S+ second.? ago|\S+ minute.? ago)(\x1b\x5b\S+m|\s)+$/) {
s/(\S+just now|\S+ second.? ago|\S+ minute.? ago)(\x1b\x5b\S+m|\s)+$//;
$current_tweet_head = "$_\n";
# print the previous tweet
print_tweet($prev_tweet_head, @prev_tweet);
sleep $sleep_interval;
undef @prev_tweet;
next;
}
# skip line after start of new tweet
if (defined $current_tweet_head) {
$prev_tweet_head = $current_tweet_head;
undef $current_tweet_head;
next;
}
# queue the contents of the tweet for printing
push @prev_tweet, $_;
}
# now loop to read new tweets as they come in
}
sub print_tweet {
my $head = shift;
return unless $head;
my $t = Text::Format->new(columns=>`tput cols`,firstIndent=>4,rightMargin=>1,leftMargin=>1);
my $text = $head . $t->paragraphs(@_);
unless ($slow) {
print $text, "\n";
return;
}
my $b;
foreach (split m/\n/, $text) {
s!https?://\S+!!g;
my $line = $_;
$line =~ s/\e\[[0-9;]*m(?:\e\[K)?//g;
if ($line =~ m/^\s+$/) {
next if $b;
$b = 1;
print "\n";
next;
}
undef $b;
foreach (split m//) {
print "$_";
Time::HiRes::sleep(rand(1) / 5) if m/[A-Za-z]/;
}
print "\n";
}
print "\n" unless $b;
return;
}
# https://stackoverflow.com/a/54816600/195656
sub read_unbuffered_line {
my $line = "";
while (sysread(STDIN, my $nextbyte, 1)) {
$line .= $nextbyte;
return $line if $nextbyte eq "\n";
}
return;
}
1;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment