logo

ap-client

CLI-based client / toolbox for ActivityPub Client-to-Servergit clone https://hacktivis.me/git/ap-client.git

ap-fetch (2244B)


  1. #!/usr/bin/env perl
  2. # AP-Client: CLI-based client / toolbox for ActivityPub
  3. # Copyright © 2020-2023 AP-Client Authors <https://hacktivis.me/git/ap-client/>
  4. # SPDX-License-Identifier: BSD-3-Clause
  5. use strict;
  6. use utf8;
  7. use open ":std", ":encoding(UTF-8)";
  8. our $VERSION = 'v0.1.4';
  9. use Getopt::Std;
  10. use LWP::UserAgent;
  11. use HTTP::Request::Common;
  12. use JSON;
  13. use App::ActivityPubClient qw(print_object);
  14. =head1 NAME
  15. ap-fetch - Fetch ActivityStream object, optionally pretty printing it
  16. =head1 SYNOPSIS
  17. B<ap-fetch> [-r|-j|-u <user:pass>] <URI>
  18. =head1 DESCRIPTION
  19. ap-fetch fetches an URI, decodes it as an ActivityStream object.
  20. =over 4
  21. =item B<-j>
  22. Pipe into jq(1)
  23. =item B<-r>
  24. Raw output, print server's output without any decoding
  25. =item B<-u user:pass>
  26. Pass username and password for HTTP Basic Auth.
  27. =back
  28. =head1 LICENSE
  29. BSD-3-Clause
  30. =cut
  31. my %options = ();
  32. my $ua = LWP::UserAgent->new;
  33. getopts("rju:", \%options);
  34. if ($#ARGV != 0) {
  35. print "usage: ap-fetch.pl [-r|-j|-u user:pass] <url>\n";
  36. print " -j Pipe into jq(1)\n";
  37. print " -r Raw output\n";
  38. print " -u user:pass HTTP Basic Auth credentials\n";
  39. print
  40. "By default, when -j and -r are absent it pipes the data into ap-represent.pl.\n";
  41. exit 1;
  42. }
  43. $ua->agent("AP-Client fetch <https://hacktivis.me/git/ap-client/>");
  44. my $req = HTTP::Request->new(GET => $ARGV[0]);
  45. $req->header('Accept' => 'application/activity+json');
  46. if (defined $options{u}) {
  47. my ($user, $password) = split(/:/, $options{u});
  48. $req->authorization_basic($user, $password);
  49. }
  50. my $res = $ua->request($req);
  51. if ($res->is_success) {
  52. my $content_type = $res->header("Content-Type");
  53. my $content_match = qr{^application/([^+]*\+)?json(; .*)?};
  54. if ($content_type =~ $content_match) {
  55. if (defined $options{r}) {
  56. print $res->content;
  57. } elsif (defined $options{j}) {
  58. open(my $pipe_out, '|-', 'jq .')
  59. or die "Couldn't open a pipe into jq: $!";
  60. print $pipe_out $res->content;
  61. close($pipe_out);
  62. } else {
  63. my $object = decode_json($res->content);
  64. print_object(1, $object);
  65. print "\n";
  66. }
  67. } else {
  68. print STDERR "Got \"$content_type\" instead of \"$content_match\"\n";
  69. exit 1;
  70. }
  71. } else {
  72. print STDERR "Got ", $res->status_line, " instead of 2xx\n";
  73. exit 1;
  74. }