App-bsky
view release on metacpan or search on metacpan
lib/App/bsky.pm view on Meta::CPAN
my $cmd = $cmd;
$cmd =~ s[[^a-z]][]gi;
if ( my $method = $self->can( 'cmd_' . $cmd ) ) {
return $method->( $self, @args );
}
}
$self->err( 'Unknown subcommand found: ' . $cmd . '. Try bsky --help', 1 ) unless @args;
}
method cmd_showprofile (@args) {
GetOptionsFromArray( \@args, 'json!' => \my $json, 'handle|H=s' => \my $handle );
return $self->cmd_help('show-profile') if scalar @args;
my $profile = $bsky->getProfile( $handle // $config->{session}{handle} );
if ($json) {
$self->say( JSON::Tiny::to_json($profile) );
}
else {
$profile->throw unless $profile;
$self->say( 'DID: %s', $profile->{did} );
$self->say( 'Handle: %s', $profile->{handle} );
$self->say( 'DisplayName: %s', $profile->{displayName} // '' );
$self->say( 'Description: %s', $profile->{description} // '' );
$self->say( 'Follows: %d', $profile->{followsCount} );
$self->say( 'Followers: %d', $profile->{followersCount} );
$self->say( 'Avatar: %s', $profile->{avatar} ) if $profile->{avatar};
$self->say( 'Banner: %s', $profile->{banner} ) if $profile->{banner};
$self->say('Blocks you: yes') if $profile->{viewer}{blockedBy} // ();
$self->say('Following: yes') if $profile->{viewer}{following} // ();
$self->say('Muted: yes') if $profile->{viewer}{muted} // ();
}
1;
}
method cmd_updateprofile (@args) {
GetOptionsFromArray(
\@args,
'avatar=s' => \my $avatar,
'banner=s' => \my $banner,
'name=s' => \my $displayName,
'description=s' => \my $description
);
$avatar // $banner // $displayName // $description // return $self->cmd_help('updateprofile');
my $profile = $bsky->getProfile( $config->{session}{handle} );
if ($profile) { # Bluesky clears them if we do not set them every time
$displayName //= $profile->{displayName};
$description //= $profile->{description};
}
if ( defined $avatar ) {
if ( $avatar =~ m[^https?://] ) {
my ( $content, $headers ) = $bsky->at->http->get($avatar);
use Carp;
$content // confess 'failed to download avatar from ' . $avatar;
# TODO: check content type HTTP::Tiny and Mojo::UserAgent do this differently
$avatar = $bsky->uploadFile( $content, $headers->{'content-type'} );
}
elsif ( -e $avatar ) {
use Path::Tiny;
$avatar = path($avatar)->slurp_raw;
my $type = substr( $avatar, 0, 2 ) eq pack 'H*',
'ffd8' ? 'image/jpeg' : substr( $avatar, 1, 3 ) eq 'PNG' ? 'image/png' : 'image/jpeg'; # XXX: Assume it's a jpeg?
$avatar = $bsky->uploadFile( $avatar, $type );
}
else {
$self->err('unsure what to do with this avatar; does not seem to be a URL or local file');
}
if ($avatar) {
$self->say( 'uploaded avatar... %d bytes', $avatar->{size} );
}
else {
$self->say('failed to upload avatar');
}
}
if ( defined $banner ) {
if ( $banner =~ m[^https?://] ) {
my ( $content, $headers ) = $bsky->at->http->get($banner);
use Carp;
$content // confess 'failed to download banner from ' . $banner;
# TODO: check content type HTTP::Tiny and Mojo::UserAgent do this differently
$banner = $bsky->uploadFile( $content, $headers->{'content-type'} );
}
elsif ( -e $banner ) {
use Path::Tiny;
$banner = path($banner)->slurp_raw;
my $type = substr( $banner, 0, 2 ) eq pack 'H*',
'ffd8' ? 'image/jpeg' : substr( $banner, 1, 3 ) eq 'PNG' ? 'image/png' : 'image/jpeg'; # XXX: Assume it's a jpeg?
$banner = $bsky->uploadFile( $banner, $type );
}
else {
$self->err('unsure what to do with this banner; does not seem to be a URL or local file');
}
if ($banner) {
$self->say( 'uploaded banner... %d bytes', $banner->{size} );
}
else {
$self->say('failed to upload banner');
}
}
my $res = $bsky->at->put_record(
'app.bsky.actor.profile',
'self',
{ defined $displayName ? ( displayName => $displayName ) : (),
defined $description ? ( description => $description ) : (),
defined $avatar ? ( avatar => $avatar ) : (),
defined $banner ? ( banner => $banner ) : ()
}
);
defined $res->{uri} ? $self->say( $res->{uri}->as_string ) : $self->err( $res->{message} );
}
method cmd_oauth ( $handle, @args ) {
my $cli = $self;
GetOptionsFromArray( \@args, 'redirect=s' => \my $redirect );
$bsky->oauth_helper(
handle => $handle,
listen => 1,
defined $redirect ? ( redirect => $redirect ) : (),
on_success => sub ($bsky_obj) {
$config->{resume} = $bsky_obj->session->_raw;
$config->{session} = $bsky_obj->session->_raw;
$cli->put_config;
$cli->say( "Authenticated as " . $bsky_obj->did );
}
);
}
method cmd_showsession (@args) {
GetOptionsFromArray( \@args, 'json!' => \my $json );
my $session = $bsky->session;
unless ($session) {
return $self->err("No active session. Run 'bsky oauth <handle>' or 'bsky login' first.");
}
if ($json) {
$self->say( JSON::Tiny::to_json( $session->_raw ) );
}
else {
$self->say( 'DID: ' . $session->did );
$self->say( 'Handle: ' . $session->handle );
$self->say( 'Email: ' . ( $session->email // 'N/A' ) );
$self->say( 'Type: ' . $session->token_type );
$self->say( 'Scopes: ' . ( $session->scope // 'N/A' ) );
}
return 1;
}
method _dump_post ( $depth, $post ) {
( run in 1.844 second using v1.01-cache-2.11-cpan-df04353d9ac )