visibility command added, a few clean up and bug fixes.

This commit is contained in:
Storm Dragon
2025-07-25 13:46:16 -04:00
parent 4eb8255975
commit b33e4fe5e1
+173 -67
View File
@@ -755,6 +755,7 @@ $lat ||= undef;
$long ||= undef;
$location ||= 0;
$linelength ||= 5000; # Generous default, will be updated from server
$post_visibility ||= "public"; # Default post visibility: public, unlisted, private, direct
# Fediverse server configuration - defaults to mastodon.social
$fediverseserver ||= "mastodon.social";
$oauthbase ||= $apibase || "${http_proto}://${fediverseserver}";
@@ -2503,82 +2504,97 @@ print $stdout "*** invalid UTF-8: partial delete of a wide character?\n";
if ($_ eq '/help' || $_ eq '/?') {
print <<'EOF';
*** BASIC COMMANDS: :a$AAOOOOOOOOOOOOOOOOOAA$a, ==================
+@A:. .:B@+ ANYTHING WITHOUT
/refresh =@B HELP!!! HELP!!! B@= A LEADING / IS
grabs the newest :a$Ao oA$a, SENT AS A TWEET!
tweets right ;AAA$a; :a$AAAAAAAAAAA; ==================
away (or tells :AOaaao:, .:oA*:. JUST TYPE TO TALK!
you if there .;=$$$OBO***+ .+aaaa$:
is nothing new) :*; :***O@Aaaa*o, ============
by thumping .+++++: o#o REMEMBER!!
the background :OOOOOOA*:::, =@o ,:::::. ============
process. .+++++++++: =@*.....=a$OOOB#; MANY COMMANDS, AND
=@OoO@BAAA#@$o, ALL TWEETS ARE
/again =@o .+aaaaa: --ASYNCHRONOUS--
displays most recent =@Aaaaaaaaaa*o*a;, and might not always
tweets, both old and =@$++=++++++:,;+aA: respond
new. ,+$@*.=O+ ...oO; oAo+. immediately!
,+o$OO=.+aA#####Oa;.*OO$o+.
/dm and /dmagain for DMs. +Ba::;oaa*$Aa=aA$*aa=;::$B:
,===O@BOOOOOOOOO#@$===,
/replies o@BOOOOOOOOO#@+ ==================
shows replies and mentions. o@BOB@B$B@BO#@+ USE + FOR A COUNT:
o@*.a@o a@o.$@+ /re +30 => last 30 replies
/quit resumes your boring life. o@B$B@o a@A$#@+ ==========================
*** BASIC COMMANDS ***
IMPORTANT: Anything without a leading / is sent as a post!
Just type to talk!
/refresh
Grabs the newest posts right away (or tells you if there
is nothing new) by checking the background process.
/again
Displays most recent posts, both old and new.
/dm and /dmagain
For direct messages.
/replies
Shows replies and mentions.
/timelines
Lists available timelines to view.
/timeline <name>
Switch to timeline (home, public, federated, notifications, etc.)
/visibility [level]
Show current post visibility or set to: public, unlisted, private, direct
/quit
Resumes your boring life.
REMEMBER: Many commands and all posts are ASYNCHRONOUS and might
not always respond immediately!
USE + FOR A COUNT: /re +30 => last 30 replies
EOF
&linein("PRESS RETURN/ENTER>");
print <<"EOF";
+- MORE COMMANDS -+ -=-=- USER STUFF -=-=-
| | /whois username displays info about username
| See the TTYverse | /again username views their most recent tweets
| home page for | /wagain username combines them all
| complete list | /follow username follow a username
| | /leave username stop following a username
+-----------------+ /dm username message send a username a DM
+--- TWEET AND DM SELECTION -------------------------------------------------+
| all DMs and tweets have menu codes (letters + number, d for DMs). example: |
| a5> <ttytter> Send me Dr Pepper http://www.floodgap.com/TTYverse |
| [DM da0][ttytter/Sun Jan 32 1969] I think you are cute |
| /reply a5 message replies to tweet a5 |
| example: /reply a5 I also like Dr Pepper |
| becomes \@ttytter I also like Dr Pepper (and is threaded) |
| /thread a5 if a5 is part of a thread (the username |
| has a \@) then show all posts up to that |
| /url a5 opens all URLs in post a5 |
| Mac OS X users, do first: /set urlopen open %U |
| Dummy terminal users, try /set urlopen lynx -dump %U | more |
| /delete a5 deletes post a5, if it's your post |
| /boost a5 boosts post a5 |
+-- Abbreviations: /re, /th, /url, /del --- menu codes wrap around at end ---+
=====> /reply, /delete and /url work for direct message menu codes too! <=====
*** MORE COMMANDS ***
USER COMMANDS:
/whois username - displays info about username
/again username - views their most recent posts
/wagain username - combines them all
/follow username - follow a username
/leave username - stop following a username
/dm username message - send a username a DM
POST AND DM SELECTION:
All DMs and posts have menu codes (letters + number, d for DMs).
Example:
a5> <user> Send me Dr Pepper http://example.com
[DM da0][user/Sun Jan 32 1969] I think you are cute
/reply a5 message - replies to post a5
/thread a5 - show all posts in thread if a5 is threaded
/url a5 - opens all URLs in post a5
/delete a5 - deletes post a5, if it's your post
/boost a5 - boosts post a5
Abbreviations: /re, /th, /url, /del
Menu codes wrap around at end.
Note: /reply, /delete and /url work for direct message menu codes too!
EOF
&linein("PRESS RETURN/ENTER>");
print <<"EOF";
*** CONFIGURATION ***
Use /set to turn on options or set them at runtime.
Use /set to turn on options or set them at runtime. There is a BIG LIST!
EXAMPLES:
/set ansi 1 - Enable ANSI colors (or use -ansi command line option)
/set verify 1 - Verify posts before posting (or use -verify option)
>> EXAMPLE: WANT ANSI? /set ansi 1
or use the -ansi command line option.
WANT TO VERIFY YOUR POSTS BEFORE POSTING? /set verify 1
or use the -verify command line option.
For more, like readline support, UTF-8, SSL, proxies, etc., see the docs.
For more options like readline support, UTF-8, SSL, proxies, etc.,
see the documentation.
** READ THE COMPLETE DOCUMENTATION: http://www.floodgap.com/software/ttytter/
*** ABOUT TTYverse ***
TTYverse $TTYverse_VERSION is (c)2012 cameron kaiser + contributors.
all rights reserved. this software is offered AS IS, with no guarantees. it
is not endorsed by any fediverse server operators or developers.
*** TTYverse: fediverse client derived from TTYtter
original TTYtter by cameron kaiser
http://www.floodgap.com/software/ttytter/
send your suggestions to me at ckaiser\@floodgap.com
TTYverse $TTYverse_VERSION - Fediverse client derived from TTYtter
Original TTYtter by Cameron Kaiser
This software is offered AS IS, with no guarantees.
It is not endorsed by any fediverse server operators or developers.
Documentation: http://www.floodgap.com/software/ttytter/
Suggestions: mention \@stormux\@social.stormux.org
EOF
return 0;
@@ -3335,7 +3351,7 @@ m#^/(un)?f(boost|a|av|ave|avorite|avourite)? ([zZ]?[a-zA-Z]?[0-9]+)$#) {
print $stdout "-- no such post (yet?): $code\n";
return 0;
}
my $target = &descape($tweet->{'user'}->{'screen_name'});
my $target = &descape($tweet->{'user'}->{'acct'} || $tweet->{'user'}->{'screen_name'});
$_ = '@' . $target . " $_";
unless ($mode eq 'v') {
$in_reply_to = $tweet->{'id_str'};
@@ -3362,7 +3378,7 @@ m#^/(un)?f(boost|a|av|ave|avorite|avourite)? ([zZ]?[a-zA-Z]?[0-9]+)$#) {
return 0;
}
# in the future, add DM in_reply_to here
my $target = &descape($dm->{'sender'}->{'screen_name'});
my $target = &descape($dm->{'sender'}->{'acct'} || $dm->{'sender'}->{'screen_name'});
$readline_completion{'@'.lc($target)}++ if ($termrl);
$_ = "/dm $target $_";
print $stdout &wwrap("(expanded to \"$_\")");
@@ -3433,6 +3449,93 @@ m#^/(un)?f(boost|a|av|ave|avorite|avourite)? ([zZ]?[a-zA-Z]?[0-9]+)$#) {
return 0;
}
# Timeline management commands
if ($_ eq '/timelines') {
print $stdout <<"EOF";
Available timelines:
/timeline home - Your main feed (default)
/timeline public - Local public timeline
/timeline federated - Federated public timeline
/timeline notifications - Your notifications (mentions, boosts, etc.)
/timeline bookmarks - Your bookmarked posts
/timeline favourites - Your favourite posts
Current timeline: home
EOF
return 0;
}
if (m#^/timeline\s+(\w+)(\s+\+\d+)?$#) {
my $timeline_name = lc($1);
my $countmaybe = $2;
$countmaybe =~ s/[^\d]//g if (length($countmaybe));
$countmaybe += 0;
my $timeline_url;
my $timeline_display_name;
# Map timeline names to API endpoints
if ($timeline_name eq 'home') {
$timeline_url = "${apibase}/timelines/home";
$timeline_display_name = "home feed";
} elsif ($timeline_name eq 'public') {
$timeline_url = "${apibase}/timelines/public?local=true";
$timeline_display_name = "local public timeline";
} elsif ($timeline_name eq 'federated') {
$timeline_url = "${apibase}/timelines/public";
$timeline_display_name = "federated timeline";
} elsif ($timeline_name eq 'notifications') {
$timeline_url = "${apibase}/notifications";
$timeline_display_name = "notifications";
} elsif ($timeline_name eq 'bookmarks') {
$timeline_url = "${apibase}/bookmarks";
$timeline_display_name = "bookmarks";
} elsif ($timeline_name eq 'favourites' || $timeline_name eq 'favorites') {
$timeline_url = "${apibase}/favourites";
$timeline_display_name = "favourites";
} else {
print $stdout "-- unknown timeline: $timeline_name\n";
print $stdout "-- use /timelines to see available timelines\n";
return 0;
}
print $stdout "-- fetching $timeline_display_name...\n" if ($verbose);
my $my_json_ref = &grabjson($timeline_url, 0, 0, $countmaybe || 20, undef, 1);
if ($timeline_name eq 'notifications') {
# Notifications have a different structure, need special handling
&dt_tdisplay($my_json_ref, "notifications");
} else {
&dt_tdisplay($my_json_ref, $timeline_name);
}
return 0;
}
# Visibility management commands
if ($_ eq '/visibility') {
my @visibilities = ('public', 'unlisted', 'private', 'direct');
print $stdout "Available post visibility levels:\n";
foreach my $vis (@visibilities) {
my $marker = ($vis eq $post_visibility) ? "* " : " ";
print $stdout "${marker}${vis}\n";
}
return 0;
}
if (m#^/visibility\s+(\w+)$#) {
my $new_visibility = lc($1);
my @valid_visibilities = ('public', 'unlisted', 'private', 'direct');
if (grep { $_ eq $new_visibility } @valid_visibilities) {
$post_visibility = $new_visibility;
print $stdout "-- post visibility set to: $post_visibility\n";
} else {
print $stdout "-- invalid visibility level: $new_visibility\n";
print $stdout "-- valid options: " . join(', ', @valid_visibilities) . "\n";
}
return 0;
}
# DMs
if ($_ eq '/dm' || $_ eq '/dmrefresh' || $_ eq '/dmr') {
&dmthump;
@@ -5333,6 +5436,7 @@ sub updatest {
}
$i .= "${payload}=${urle}${user_name_dm}" unless ($rt_id);
$i .= "id=$rt_id" if ($rt_id);
$i .= "visibility=${post_visibility}&" unless ($rt_id || length($user_name_dm));
$slowpost += 0; if ($slowpost && !$script && !$status && !$silent) {
if($pid = open(SLOWPOST, '-|')) {
# pause background so that it doesn't kill itself
@@ -6141,7 +6245,7 @@ sub defaultautocompletion {
'/wagain', '/whois', '/thump', '/dm',
'/refresh', '/dmagain', '/set', '/help',
'/reply', '/url', '/thread', '/retweet', '/replyall',
'/replies', '/ruler', '/exit', '/me', '/vcheck',
'/replies', '/timelines', '/timeline', '/visibility', '/ruler', '/exit', '/me', '/vcheck',
'/oretweet', '/eretweet', '/fretweet', '/liston',
'/listoff', '/dmsent', '/rtsof', '/rtson', '/rtsoff',
'/lists', '/withlist', '/add', '/padd', '/push',
@@ -6307,7 +6411,7 @@ sub get_tweet {
kill $SIGUSR2, $child if ($child);
print C "pipet $code ----------\n";
while(length($k) < 1024) {
sysread(W, $l, 1024);
read(W, $l, 1024);
$k .= $l;
}
return undef if ($k !~ /[^\s]/);
@@ -6356,7 +6460,7 @@ sub get_dm {
kill $SIGUSR2, $child if ($child); # prime pipe
print C "piped $code ----------\n"; # internally two alphanum, recall
while(length($k) < 1024) {
sysread(W, $l, 1024);
read(W, $l, 1024);
$k .= $l;
}
return undef if ($k !~ /[^\s]/);
@@ -6386,7 +6490,7 @@ sub getbackgroundkey {
"DEFAULT";
print C substr(unpack("${pack_magic}H*", $ref).$space_pad, 0, 1024);
while(length($k) < 1024) {
sysread(W, $l, 1024);
read(W, $l, 1024);
$k .= $l;
}
$k =~ s/[^0-9a-fA-F]//g;
@@ -7644,6 +7748,7 @@ sub map_single_status {
$user->{'screen_name'} = $user->{'username'} if exists($user->{'username'});
$user->{'name'} = $user->{'display_name'} if exists($user->{'display_name'});
$user->{'profile_image_url'} = $user->{'avatar'} if exists($user->{'avatar'});
# Keep acct field for full handle (username@domain.com)
}
# Recursively map reblogged status
@@ -7661,6 +7766,7 @@ sub map_user_object {
$user->{'screen_name'} = $user->{'username'} if exists($user->{'username'});
$user->{'name'} = $user->{'display_name'} if exists($user->{'display_name'});
$user->{'profile_image_url'} = $user->{'avatar'} if exists($user->{'avatar'});
# Keep acct field for full handle (username@domain.com)
$user->{'followers_count'} = $user->{'followers_count'} if exists($user->{'followers_count'});
$user->{'friends_count'} = $user->{'following_count'} if exists($user->{'following_count'});
$user->{'statuses_count'} = $user->{'statuses_count'} if exists($user->{'statuses_count'});