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; $long ||= undef;
$location ||= 0; $location ||= 0;
$linelength ||= 5000; # Generous default, will be updated from server $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 # Fediverse server configuration - defaults to mastodon.social
$fediverseserver ||= "mastodon.social"; $fediverseserver ||= "mastodon.social";
$oauthbase ||= $apibase || "${http_proto}://${fediverseserver}"; $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 '/?') { if ($_ eq '/help' || $_ eq '/?') {
print <<'EOF'; print <<'EOF';
*** BASIC COMMANDS: :a$AAOOOOOOOOOOOOOOOOOAA$a, ================== *** BASIC COMMANDS ***
+@A:. .:B@+ ANYTHING WITHOUT
/refresh =@B HELP!!! HELP!!! B@= A LEADING / IS IMPORTANT: Anything without a leading / is sent as a post!
grabs the newest :a$Ao oA$a, SENT AS A TWEET! Just type to talk!
tweets right ;AAA$a; :a$AAAAAAAAAAA; ==================
away (or tells :AOaaao:, .:oA*:. JUST TYPE TO TALK! /refresh
you if there .;=$$$OBO***+ .+aaaa$: Grabs the newest posts right away (or tells you if there
is nothing new) :*; :***O@Aaaa*o, ============ is nothing new) by checking the background process.
by thumping .+++++: o#o REMEMBER!!
the background :OOOOOOA*:::, =@o ,:::::. ============ /again
process. .+++++++++: =@*.....=a$OOOB#; MANY COMMANDS, AND Displays most recent posts, both old and new.
=@OoO@BAAA#@$o, ALL TWEETS ARE
/again =@o .+aaaaa: --ASYNCHRONOUS-- /dm and /dmagain
displays most recent =@Aaaaaaaaaa*o*a;, and might not always For direct messages.
tweets, both old and =@$++=++++++:,;+aA: respond
new. ,+$@*.=O+ ...oO; oAo+. immediately! /replies
,+o$OO=.+aA#####Oa;.*OO$o+. Shows replies and mentions.
/dm and /dmagain for DMs. +Ba::;oaa*$Aa=aA$*aa=;::$B:
,===O@BOOOOOOOOO#@$===, /timelines
/replies o@BOOOOOOOOO#@+ ================== Lists available timelines to view.
shows replies and mentions. o@BOB@B$B@BO#@+ USE + FOR A COUNT:
o@*.a@o a@o.$@+ /re +30 => last 30 replies /timeline <name>
/quit resumes your boring life. o@B$B@o a@A$#@+ ========================== 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 EOF
&linein("PRESS RETURN/ENTER>"); &linein("PRESS RETURN/ENTER>");
print <<"EOF"; print <<"EOF";
+- MORE COMMANDS -+ -=-=- USER STUFF -=-=- *** MORE COMMANDS ***
| | /whois username displays info about username
| See the TTYverse | /again username views their most recent tweets USER COMMANDS:
| home page for | /wagain username combines them all /whois username - displays info about username
| complete list | /follow username follow a username /again username - views their most recent posts
| | /leave username stop following a username /wagain username - combines them all
+-----------------+ /dm username message send a username a DM /follow username - follow a username
+--- TWEET AND DM SELECTION -------------------------------------------------+ /leave username - stop following a username
| all DMs and tweets have menu codes (letters + number, d for DMs). example: | /dm username message - send a username a DM
| a5> <ttytter> Send me Dr Pepper http://www.floodgap.com/TTYverse |
| [DM da0][ttytter/Sun Jan 32 1969] I think you are cute | POST AND DM SELECTION:
| /reply a5 message replies to tweet a5 | All DMs and posts have menu codes (letters + number, d for DMs).
| example: /reply a5 I also like Dr Pepper | Example:
| becomes \@ttytter I also like Dr Pepper (and is threaded) | a5> <user> Send me Dr Pepper http://example.com
| /thread a5 if a5 is part of a thread (the username | [DM da0][user/Sun Jan 32 1969] I think you are cute
| has a \@) then show all posts up to that |
| /url a5 opens all URLs in post a5 | /reply a5 message - replies to post a5
| Mac OS X users, do first: /set urlopen open %U | /thread a5 - show all posts in thread if a5 is threaded
| Dummy terminal users, try /set urlopen lynx -dump %U | more | /url a5 - opens all URLs in post a5
| /delete a5 deletes post a5, if it's your post | /delete a5 - deletes post a5, if it's your post
| /boost a5 boosts post a5 | /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! <===== Abbreviations: /re, /th, /url, /del
Menu codes wrap around at end.
Note: /reply, /delete and /url work for direct message menu codes too!
EOF EOF
&linein("PRESS RETURN/ENTER>"); &linein("PRESS RETURN/ENTER>");
print <<"EOF"; 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 For more options like readline support, UTF-8, SSL, proxies, etc.,
or use the -ansi command line option. see the documentation.
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.
** READ THE COMPLETE DOCUMENTATION: http://www.floodgap.com/software/ttytter/ *** ABOUT TTYverse ***
TTYverse $TTYverse_VERSION is (c)2012 cameron kaiser + contributors. TTYverse $TTYverse_VERSION - Fediverse client derived from TTYtter
all rights reserved. this software is offered AS IS, with no guarantees. it Original TTYtter by Cameron Kaiser
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
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 EOF
return 0; 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"; print $stdout "-- no such post (yet?): $code\n";
return 0; return 0;
} }
my $target = &descape($tweet->{'user'}->{'screen_name'}); my $target = &descape($tweet->{'user'}->{'acct'} || $tweet->{'user'}->{'screen_name'});
$_ = '@' . $target . " $_"; $_ = '@' . $target . " $_";
unless ($mode eq 'v') { unless ($mode eq 'v') {
$in_reply_to = $tweet->{'id_str'}; $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; return 0;
} }
# in the future, add DM in_reply_to here # 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); $readline_completion{'@'.lc($target)}++ if ($termrl);
$_ = "/dm $target $_"; $_ = "/dm $target $_";
print $stdout &wwrap("(expanded to \"$_\")"); 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; 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 # DMs
if ($_ eq '/dm' || $_ eq '/dmrefresh' || $_ eq '/dmr') { if ($_ eq '/dm' || $_ eq '/dmrefresh' || $_ eq '/dmr') {
&dmthump; &dmthump;
@@ -5333,6 +5436,7 @@ sub updatest {
} }
$i .= "${payload}=${urle}${user_name_dm}" unless ($rt_id); $i .= "${payload}=${urle}${user_name_dm}" unless ($rt_id);
$i .= "id=$rt_id" if ($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) { $slowpost += 0; if ($slowpost && !$script && !$status && !$silent) {
if($pid = open(SLOWPOST, '-|')) { if($pid = open(SLOWPOST, '-|')) {
# pause background so that it doesn't kill itself # pause background so that it doesn't kill itself
@@ -6141,7 +6245,7 @@ sub defaultautocompletion {
'/wagain', '/whois', '/thump', '/dm', '/wagain', '/whois', '/thump', '/dm',
'/refresh', '/dmagain', '/set', '/help', '/refresh', '/dmagain', '/set', '/help',
'/reply', '/url', '/thread', '/retweet', '/replyall', '/reply', '/url', '/thread', '/retweet', '/replyall',
'/replies', '/ruler', '/exit', '/me', '/vcheck', '/replies', '/timelines', '/timeline', '/visibility', '/ruler', '/exit', '/me', '/vcheck',
'/oretweet', '/eretweet', '/fretweet', '/liston', '/oretweet', '/eretweet', '/fretweet', '/liston',
'/listoff', '/dmsent', '/rtsof', '/rtson', '/rtsoff', '/listoff', '/dmsent', '/rtsof', '/rtson', '/rtsoff',
'/lists', '/withlist', '/add', '/padd', '/push', '/lists', '/withlist', '/add', '/padd', '/push',
@@ -6307,7 +6411,7 @@ sub get_tweet {
kill $SIGUSR2, $child if ($child); kill $SIGUSR2, $child if ($child);
print C "pipet $code ----------\n"; print C "pipet $code ----------\n";
while(length($k) < 1024) { while(length($k) < 1024) {
sysread(W, $l, 1024); read(W, $l, 1024);
$k .= $l; $k .= $l;
} }
return undef if ($k !~ /[^\s]/); return undef if ($k !~ /[^\s]/);
@@ -6356,7 +6460,7 @@ sub get_dm {
kill $SIGUSR2, $child if ($child); # prime pipe kill $SIGUSR2, $child if ($child); # prime pipe
print C "piped $code ----------\n"; # internally two alphanum, recall print C "piped $code ----------\n"; # internally two alphanum, recall
while(length($k) < 1024) { while(length($k) < 1024) {
sysread(W, $l, 1024); read(W, $l, 1024);
$k .= $l; $k .= $l;
} }
return undef if ($k !~ /[^\s]/); return undef if ($k !~ /[^\s]/);
@@ -6386,7 +6490,7 @@ sub getbackgroundkey {
"DEFAULT"; "DEFAULT";
print C substr(unpack("${pack_magic}H*", $ref).$space_pad, 0, 1024); print C substr(unpack("${pack_magic}H*", $ref).$space_pad, 0, 1024);
while(length($k) < 1024) { while(length($k) < 1024) {
sysread(W, $l, 1024); read(W, $l, 1024);
$k .= $l; $k .= $l;
} }
$k =~ s/[^0-9a-fA-F]//g; $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->{'screen_name'} = $user->{'username'} if exists($user->{'username'});
$user->{'name'} = $user->{'display_name'} if exists($user->{'display_name'}); $user->{'name'} = $user->{'display_name'} if exists($user->{'display_name'});
$user->{'profile_image_url'} = $user->{'avatar'} if exists($user->{'avatar'}); $user->{'profile_image_url'} = $user->{'avatar'} if exists($user->{'avatar'});
# Keep acct field for full handle (username@domain.com)
} }
# Recursively map reblogged status # Recursively map reblogged status
@@ -7661,6 +7766,7 @@ sub map_user_object {
$user->{'screen_name'} = $user->{'username'} if exists($user->{'username'}); $user->{'screen_name'} = $user->{'username'} if exists($user->{'username'});
$user->{'name'} = $user->{'display_name'} if exists($user->{'display_name'}); $user->{'name'} = $user->{'display_name'} if exists($user->{'display_name'});
$user->{'profile_image_url'} = $user->{'avatar'} if exists($user->{'avatar'}); $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->{'followers_count'} = $user->{'followers_count'} if exists($user->{'followers_count'});
$user->{'friends_count'} = $user->{'following_count'} if exists($user->{'following_count'}); $user->{'friends_count'} = $user->{'following_count'} if exists($user->{'following_count'});
$user->{'statuses_count'} = $user->{'statuses_count'} if exists($user->{'statuses_count'}); $user->{'statuses_count'} = $user->{'statuses_count'} if exists($user->{'statuses_count'});