From 0d78ee671fb0c0aeda84e15d8c01ad5a62275b29 Mon Sep 17 00:00:00 2001 From: Storm Dragon Date: Sun, 27 Jul 2025 23:07:12 -0400 Subject: [PATCH] Getting close to finished refactor. Also, gotta figure out why no data is reported even on successful retrieval. --- LICENSE | 255 ++++++++++++++++++++++++++++++++++++++++++++++++++++ ttyverse.pl | 115 +++++++++++++++++------- 2 files changed, 340 insertions(+), 30 deletions(-) create mode 100755 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100755 index 0000000..9f62b50 --- /dev/null +++ b/LICENSE @@ -0,0 +1,255 @@ + Floodgap Free Software License + + The author of your software has chosen to distribute it under the + Floodgap Free Software License. Although this software is without cost, + it is not released under Copyleft or GPL, and there are differences + which you should read. Your use of this software package constitutes + your binding acceptance without restriction. + + This software is without cost + + The Floodgap Free Software License (FFSL) has one overriding mandate: + that software using it, or derivative works based on software that uses + it, must be free. By free we mean simply "free as in beer" -- you may + put your work into open or closed source packages as you see fit, + whether or not you choose to release your changes or updates publicly, + but you must not ask any fee for it. (There are certain exceptions for + for-profit use which we will discuss below.) + + Definitions and terms + + Author + The declared copyright owner of this software package. + + Binary + A pre-compiled or pre-interpreted bytecode or machine language + representation of a software package not designed for further + modification and tied to a particular platform or architecture. + + Derivative work + Any distribution (q.v.) that contains any modification to or + deviation from the official reference distribution (q.v.); or + any software package significantly based on or integrally + including the source code for its features, including but not + limited to supersets; subsets of a significant proportion; + in-place patched changes to source or binary files; linking in + as a library; binary-only distributions if the original package + included source (even if the source was not modified prior to + compilation); or translations to another programming language, + architecture or operating system environment. Derivative works + of packages released under this license are also considered + subject to this license. + + However, a software package that requires this package but does + not include it or is not based upon it, even if it will not + operate without it, is not considered a derivative work. For + example, interpreted programs requiring an interpreter issued + under this license, assuming they are not distributed with any + portion of the interpreter, are not derivative works. + + Distribution + A packaged release of this software, either the author's + original work (the "reference distribution") or a derivative + work based upon it. + + Reference distribution + A packaged release of this software explicitly designated as the + official release, written by or on behalf of the Author with his + or her explicit designation as official. Only exact copies of + the reference distribution may be called reference + distributions; all other forms are derivative works. + + Source code + The human-readable programming instructions of the package which + might be easily read as text and subsequently edited, but + requiring compilation or interpretation into binary before being + directly useable. + + What you are permitted to do under this license + + Pursuant to the remainder of the terms below, + * You may freely use, copy, and disseminate this software package for + any non-commercial purpose as well as the commercial purposes + permitted below. + * You may freely modify this package, including source code if + available. Your modifications need not be released, although you + are encouraged to do so. + * You may release your derivative works based upon this software in + purely binary (non-source) form if you choose. You are not + obligated to release any portion of your source code openly, + although you are encouraged to do so. + * If this package is a tool used for generation, compilation or + maintenance of works, including but not limited to readable + documents, software packages or images (for example, compilers, + interpreters, translators, linkers, editors, assemblers or + typesetters), you may freely use it for that purpose, commercial or + otherwise, as the works made by this package are not considered + subject to this license unless specified otherwise within and may + be distributed under any desired license and/or offered for sale or + rental. Any run-time library or run-time code section linked into + the output by a compiler or similar code-generating tool governed + by this license is considered to be an integral part of the output, + and its presence does not subject the generated work to this + license either. (This is, of course, assuming you are not using + said tools to generate a derivative work based on this package in + violation of the other license terms.) + However, if you are linking or including a separately distributed + library that is under this license, no matter what tool you are + using to do the linking or inclusion, you are then considered to be + making a derivative work based on that library and your work does + fall under this license. To avoid this, do not include the library + with your work (even though it needs the library to function) and + instead offer the library separately without cost. + * In addition to non-commercial use and the uses permitted above, you + may use this software package in any for-profit endeavour as long + as it does not involve the specific sale or rental of this package. + Some specific but by no means exhaustive examples are listed below. + Note that some of these situations may require additional action be + taken to ensure compliance. + + If this package or a derivative work allows you to serve data + or make data available to others (for example, web servers, + mail servers, gopher servers, etc.), you may use it to serve + any commercial content or in any commercial setting whether + you choose to charge a fee or not, as you are considered to be + earning income from the content you serve and/or the services + facilitated by your business and not from the sale of this + package itself. (This is, of course, assuming that you are not + charging a fee for sale or rental of this package or a + derivative work based on this package in violation of the + other license terms.) Similarly, any data you may acquire from + the use of this package is yours, and not governed by this + license in any way even if for-profit. + + If you are selling a product that includes this package or a + derivative work either as part of your product's requirements + for function or as a bundled extra, such as an operating + system distribution, you may charge a fee for your product as + long as you also make this package or said derivative work + available for free separately (such as by download or link + back to this package's site), as you are considered to be + requesting a fee for your own product and the package is + merely included as a convenience to your users. + + If you offer installation of this package or a derivative work + as a service, you may charge a fee for the act of installation + as long as you also make this package or said derivative work + available for free (such as by download or link back to this + package's site), as you are considered to be requesting a fee + for the act of installation and not for the software you are + installing. + + The Author may also grant, in writing, other specified + exemptions for your particular commercial purpose that do not + contravene the spirit of this license or any license terms + this package additionally carries. + * In your derivative works based on this package, you may choose to + offer warranty support or guarantees of performance. This does not + in any way make the original Author legally, financially or in any + other respect liable for claims issued under your warranty or + guarantee, and you are solely responsible for the fulfillment of + your terms even if the Author of the work you have based your work + upon offers his or her own. + * In your derivative works based on this package, you may further + restrict the acceptable uses of your package or situations in which + it may be employed as long as you clearly state that your terms + apply only to your derivative work and not to the original + reference distribution. However, you may not countermand or ignore, + directly or otherwise, any restriction already made in the + reference distribution's license, including in this document + itself, in similar fashion to other licenses allowing compatible + licenses to co-govern a particular package's use. + + What you must not do under this license + + Remember that these limits apply only to redistribution of a reference + distribution, or to a true derivative work. If your project does not + include this package or code based upon it, even if it requires this + package to function, it is not considered subject to this license or + these restrictions. + * You must not charge a fee for purchase or rental of this package or + any derivative work based on this package. It is still possible to + use this package in a commercial environment, however -- see What + you are permitted to do under this license. + * You must not countermand or ignore, directly or otherwise, the + restrictions already extant in this package's license in your + derivative work based on it. As a corollary, you must not place + your derivative work under a secondary license or description of + terms that conflicts with it (for example, this license is not + compatible with the GNU Public License). + * You must not label any modified distribution of this package as a + reference or otherwise official distribution without the permission + of the original Author or Authors. You must clearly specify that + your modified work is a derivative work, including binary-only + releases if the original included source code and you do not even + if you did not modify the source prior to compilation. + + What you must do under this license + + * You must agree to all terms specified (agreement to which is + unconditionally signified by your usage, modification or + repurposing of this package), or to remove the package from your + computer and not use it further. + * In the absence of any specific offer for redress or assistance + under warranty or guarantee of performance that the Author of this + package might make, you must agree to accept any and all liability + that may come from the use of this package, proper or improper, + real or imagined, and certify without condition that you use this + product at your own risk with no guarantee of function, + merchantability or fitness for a particular purpose. If such offer + of redress or assistance is extended, it is fulfillable only by the + Author who extended the offer, which might not necessarily be this + Author, nor might it be the Authors of any packages it might be + based upon. + * If you choose to publicly redistribute this package or create a + derivative work based on this package, you must make it available + without any purchase or rental fee of any kind. + * If you choose to create a derivative work based on this package, + your derivative work must be copyrighted, and must be governed + under (at a minimum) the original package's license, which will + necessarily include all terms noted here. As such, if you choose to + distribute your derivative work, you must include a human-readable + license in your distribution containing all restrictions of use, + necessarily including this license, and any additional restrictions + the Author has mandated that do not contravene this license which + you and users of your derivative work must also honour. + * If you choose to create and distribute a derivative work based on + this package, your derivative work must clearly make reference to + this package, any other packages your work or the original work + might be based on, and all applicable copyrights, either in your + documentation, your work's standard human-readable output, or both. + A suggested method might be + + Contains or is based on the Foo software package. + Copyright (C) 2112 D. Original Author. All rights reserved. + http://their.web.site.invalid/ + + Additional notes + + Enforcement is the responsibility of the Author. However, violation of + this license may subject you to criminal and civil penalties depending + on your country. + + This package is bound by the version of license that accompanies it. + Future official versions of a particular package may use a more updated + license, and you should always review the license before use. This + license's most current version is always available from the following + locations: + + [1]http://www.floodgap.com/software/ffsl/ + [2]gopher://gopher.floodgap.com/1/ffsl/ + + This license is version 1, dated 19 November 2006. + + This license is copyright © 2006 Cameron Kaiser. All rights reserved. + The text of this license is available for re-use and re-distribution + under the Creative Commons. The use of the term "Floodgap Free Software + License" does not imply endorsement of packages using this license by + Floodgap Systems or by Cameron Kaiser. Modified licenses using portions + of these terms may refer to themselves as modified FFSL, with the + proviso that their modifications be clearly marked in accordance with + the Creative Commons Attribution-ShareAlike 2.5 License. + + Only the text of this license, and not programs covered by this + license, is so offered under Creative Commons. + +References + + 1. http://www.floodgap.com/software/ffsl/ + 2. gopher://gopher.floodgap.com/1/ffsl/ diff --git a/ttyverse.pl b/ttyverse.pl index d17f0b6..a6957e0 100755 --- a/ttyverse.pl +++ b/ttyverse.pl @@ -4002,10 +4002,15 @@ EOF $comm = $_; } + # Get list ID for fediverse API operations + my $list_id = &lookup_list_id($lname); + if (!$list_id && $comm ne 'create') { + print $stdout "*** list '$lname' not found; use /lists to see available lists\n"; + return 0; + } + my $return; - # this is a fediverse bug -- it will not give you the - # new slug in the returned hash. - my $state = "modified list $lname (WAIT! then /lists to see new slug)"; + my $state = "modified list $lname"; if ($comm eq 'create') { my $desc; ($args, $desc) = split(/\s+/, $args, 2) @@ -4021,25 +4026,26 @@ EOF $return = &postjson($creliurl, "${desc}mode=$args&name=$lname"); } elsif ($comm eq 'private' || $comm eq 'public') { - $return = &postjson($modifyliurl, - "mode=$comm&owner_screen_name=${whoami}&slug=${lname}"); + my $url = $modifyliurl; + $url =~ s/%I/$list_id/; + $return = &postjson($url, "replies_policy=$comm"); } elsif ($comm eq 'desc' || $comm eq 'description') { if (!length($args)) { print $stdout "-- $comm needs an argument\n"; return 0; } - $return = &postjson($modifyliurl, - "description=".&url_oauth_sub($args). - "&owner_screen_name=${whoami}&slug=${lname}"); + my $url = $modifyliurl; + $url =~ s/%I/$list_id/; + $return = &postjson($url, "description=".&url_oauth_sub($args)); } elsif ($comm eq 'name') { if (!length($args)) { print $stdout "-- $comm needs an argument\n"; return 0; } - $return = &postjson($modifyliurl, - "name=".&url_oauth_sub($args). - "&owner_screen_name=${whoami}&slug=${lname}"); - $state = "RENAMED list $lname (WAIT! then /lists to see new slug)"; + my $url = $modifyliurl; + $url =~ s/%I/$list_id/; + $return = &postjson($url, "title=".&url_oauth_sub($args)); + $state = "renamed list $lname to $args"; } elsif ($comm eq 'add' || $comm eq 'adduser' || ($comm eq 'delete' && length($args))) { my $u = ($comm eq 'delete') ? $deluliurl : $adduliurl; @@ -4056,11 +4062,25 @@ EOF print $stdout "-- illegal/missing argument\n"; return 0; } - print $stdout "--- warning: user list not checked\n"; - $return = &postjson($u, - "owner_screen_name=${whoami}". - "&screen_name=".&url_oauth_sub($args). - "&slug=${lname}"); + # Convert usernames to account IDs for fediverse API + my @usernames = split(/,/, $args); + my @account_ids = (); + for my $username (@usernames) { + $username =~ s/^@//; # Remove @ if present + my $account_id = &lookup_account_id($username); + if (!$account_id) { + print $stdout "-- ERROR: Could not find account for user: $username\n"; + return 0; + } + push @account_ids, $account_id; + } + + my $url = $u; + $url =~ s/%I/$list_id/; + + # Fediverse API expects account_ids array parameter + my $account_ids_param = join(',', @account_ids); + $return = &postjson($url, "account_ids=$account_ids_param"); } elsif ($comm eq 'delete' && !length($args)) { $state = "deleted list $lname"; print $stdout @@ -4071,8 +4091,9 @@ EOF print $stdout "-- ok, list is NOT deleted.\n"; return 0; } - $return = &postjson($delliurl, - "owner_screen_name=${whoami}&slug=${lname}"); + my $url = $delliurl; + $url =~ s/%I/$list_id/; + $return = &postjson($url, ""); if ($return) { # check and see if this is in our autolists. # if it is, delete it there too. @@ -4153,6 +4174,12 @@ EOF print $stdout "-- specify username only\n"; return 0; } + + # Fediverse privacy: only allow access to own lists + if ($uname ne $whoami) { + print $stdout "-- Sorry, fediverse only allows access to your own lists (privacy feature)\n"; + return 0; + } $countmaybe =~ s/[^\d]//g if (length($countmaybe)); $countmaybe += 0; @@ -4166,12 +4193,26 @@ EOF my $printed = 0; my $json_ref = undef; my @usarray = undef; shift(@usarray); # force underflow - my $furl = (length($lname)) ? ($getliurl."?owner_") - : ($mode eq '') ? ($getlisurl."?") - : ($mode eq 'fo') ? ($getuliurl."?") - : ($getufliurl."?"); - $furl .= "screen_name=${uname}"; - $furl .= "&slug=${lname}" if (length($lname)); + + # Build fediverse API URL + my $furl; + if (length($lname)) { + # Get specific list members + my $list_id = &lookup_list_id($lname); + if (!$list_id) { + print $stdout "*** list '$lname' not found; use /lists to see available lists\n"; + return 0; + } + $furl = $getliurl; + $furl =~ s/%I/$list_id/; + } elsif ($mode eq '') { + # Get all lists for user + $furl = $getlisurl; + } else { + # Following/followers of lists - not supported in fediverse + print $stdout "-- Sorry, list following/followers not supported in fediverse (privacy feature)\n"; + return 0; + } LABIO: while($countmaybe--) { if(!scalar(@usarray)) { @@ -5585,15 +5626,29 @@ sub refresh { # the list. if (scalar(@listlist)) { foreach $k (@listlist) { + # Fediverse privacy: only allow access to own lists + if ($k->[0] ne $whoami) { + print $stdout "-- Skipping $k->[0]/$k->[1]: fediverse only allows access to your own lists (privacy feature)\n" if ($verbose); + next; + } + + # Convert list name to ID for fediverse API + my $list_id = &lookup_list_id($k->[1]); + if (!$list_id) { + print $stdout "-- Skipping $k->[1]: list not found\n" if ($verbose); + next; + } + + # Build fediverse list timeline URL + my $list_url = $statusliurl; + $list_url =~ s/%I/$list_id/; + # always use fetch_id - my $r = &grabjson( - "${statusliurl}?owner_screen_name=".$k->[0].'&slug='.$k->[1], + my $r = &grabjson($list_url, $fetch_id, 0, (($last_id) ? 250 : $fetchwanted), { "type" => "list", - "payload" => ($k->[0] ne $whoami) ? - "$k->[0]/$k->[1]" : - "$k->[1]" + "payload" => "$k->[1]" }, 1); push(@streams, $r) if (defined($r) && ref($r) eq 'ARRAY' &&