Skip to content

Commit

Permalink
Adding likes, like, unlike, and invite-codes commands
Browse files Browse the repository at this point in the history
  • Loading branch information
sanko committed Jan 27, 2024
1 parent e9e0ee2 commit 155df62
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 34 deletions.
31 changes: 24 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,30 +147,29 @@ post "This is a test"

Create a new post.

## vote
## like

```
bsky vote [uri] --down
bsky like [uri]
```

Vote on the post.
Like a post.

TODO

### Options

```
uri
--down optional, if true, a downvote is cast, otherwise, the post is voted up
```

## votes
## likes

```
bsky votes [uri]
bsky likes [uri]
```

Show votes of the post.
Show likes on a post.

TODO

Expand Down Expand Up @@ -376,6 +375,24 @@ Show notifications.
--json boolean flag; content is printed as JSON objects if given
```

## invite-codes

```
bsky invite-codes
bsky invite-codes --json
```

Show invite codes.

Note that you must be logged in with the account password to view invite codes.

### Options

```
--json boolean flag; content is printed as JSON objects if given
```

## add-app-password

```
Expand Down
61 changes: 48 additions & 13 deletions lib/App/bsky.pm
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ package App::bsky 0.02 {
#$algorithm //= (), $limit //= (), $cursor //= ()
if ($json) {
$self->say( JSON::Tiny::to_json( $_->_raw ) ) for @{ $tl->{feed} };
$self->say( JSON::Tiny::to_json [ map { $_->_raw } @{ $tl->{feed} } ] );
}
else { # TODO: filter where $type ne 'app.bsky.feed.post'
for my $post ( @{ $tl->{feed} } ) {
Expand Down Expand Up @@ -300,12 +300,39 @@ package App::bsky 0.02 {
$bsky->delete($rkey);
}
method cmd_vote ( $uri, $bool //= !!1 ) {
...;
method cmd_like ($uri) { # can take the post uri
#~ GetOptionsFromArray( \@args, 'json!' => \my $json );
my $res = $bsky->like($uri);
$res // return;
$self->say( $res->{uri}->as_string );
}
method cmd_votes ($uri) {
...;
method cmd_unlike ($uri) { # can take the post uri or the like uri
$bsky->unlike($uri);
}
method cmd_likes ( $uri, @args ) {
GetOptionsFromArray( \@args, 'json!' => \my $json );
my @likes;
my $cursor = ();
do {
my $likes = $bsky->feed_getLikes( $uri, undef, 100, $cursor );
push @likes, @{ $likes->{likes} };
$cursor = $likes->{cursor};
} while ($cursor);
if ($json) {
$self->say( JSON::Tiny::to_json [ map { $_->_raw } @likes ] );
}
else {
$self->say(
'%s%s%s%s (%s)',
color('red'), $_->actor->handle->_raw,
color('reset'), defined $_->actor->displayName ? ' [' . $_->actor->displayName . ']' : '',
$_->createdAt->_raw
) for @likes;
}
scalar @likes;
}
method cmd_repost ($uri) {
Expand Down Expand Up @@ -340,7 +367,7 @@ package App::bsky 0.02 {
$cursor = $follows->{cursor};
} while ($cursor);
if ($json) {
$self->say( JSON::Tiny::to_json $_->_raw ) for @follows;
$self->say( JSON::Tiny::to_json [ map { $_->_raw } @follows ] );
}
else {
for my $follow (@follows) {
Expand All @@ -366,7 +393,7 @@ package App::bsky 0.02 {
}
} while ($cursor);
if ($json) {
$self->say( JSON::Tiny::to_json $_->_raw ) for @followers;
$self->say( JSON::Tiny::to_json [ map { $_->_raw } @followers ] );
}
else {
for my $follower (@followers) {
Expand Down Expand Up @@ -401,7 +428,7 @@ package App::bsky 0.02 {
$cursor = $follows->{cursor};
} while ($cursor);
if ($json) {
$self->say( JSON::Tiny::to_json $_->_raw ) for @blocks;
$self->say( JSON::Tiny::to_json [ map { $_->_raw } @blocks ] );
}
else {
for my $follow (@blocks) {
Expand Down Expand Up @@ -432,7 +459,7 @@ package App::bsky 0.02 {
}
method cmd_notifications (@args) {
GetOptionsFromArray( \@args, 'all|a' => \my $all, 'json' => \my $json );
GetOptionsFromArray( \@args, 'all|a' => \my $all, 'json!' => \my $json );
my @notes;
my $cursor = ();
do {
Expand All @@ -443,7 +470,7 @@ package App::bsky 0.02 {
}
} while ($cursor);
if ($json) {
$self->say( JSON::Tiny::to_json $_->_raw ) for @notes;
$self->say( JSON::Tiny::to_json [ map { $_->_raw } @notes ] );
}
else {
for my $note (@notes) {
Expand Down Expand Up @@ -472,12 +499,20 @@ package App::bsky 0.02 {
$self->cmd_notifications(@args);
}
method cmd_invitecodes () {
...;
method cmd_invitecodes (@args) {
GetOptionsFromArray( \@args, 'json!' => \my $json, 'used!' => \my $used );
my $res = $bsky->server_getAccountInviteCodes($used);
if ($json) {
$self->say( JSON::Tiny::to_json [ map { $_->_raw } @{ $res->{codes} } ] );
}
else {
$self->say( $_->code . ( $_->available ? '' : ' [unavailable]' ) . ( $_->disabled ? ' [disabled]' : '' ) ) for @{ $res->{codes} };
}
scalar @{ $res->{codes} };
}
method cmd_listapppasswords (@args) {
GetOptionsFromArray( \@args, 'json' => \my $json );
GetOptionsFromArray( \@args, 'json!' => \my $json );
my $passwords = $bsky->server_listAppPasswords;
my @passwords = @{ $passwords->{passwords} };
if ($json) {
Expand Down
27 changes: 20 additions & 7 deletions script/bsky
Original file line number Diff line number Diff line change
Expand Up @@ -128,24 +128,23 @@ Show a thread.

Create a new post.

=head2 vote
=head2 like

bsky vote [uri] --down
bsky like [uri]

Vote on the post.
Like a post.

TODO

=head3 Options

uri
--down optional, if true, a downvote is cast, otherwise, the post is voted up

=head2 votes
=head2 likes

bsky votes [uri]
bsky likes [uri]

Show votes of the post.
Show likes on a post.

TODO

Expand Down Expand Up @@ -305,6 +304,20 @@ Show notifications.
--all boolean flag, show all notifications
--json boolean flag; content is printed as JSON objects if given

=head2 invite-codes

bsky invite-codes

bsky invite-codes --json

Show invite codes.

Note that you must be logged in with the account password to view invite codes.

=head3 Options

--json boolean flag; content is printed as JSON objects if given

=head2 add-app-password

bsky add-app-password "Your app name"
Expand Down
2 changes: 1 addition & 1 deletion t/00_compile.t
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ subtest 'commands' => sub {
cmd_stream
cmd_thread
cmd_post cmd_delete
cmd_vote cmd_votes
cmd_like cmd_unlike cmd_likes
cmd_repost cmd_reposts
cmd_follow cmd_unfollow cmd_follows cmd_followers
cmd_block cmd_unblock cmd_blocks
Expand Down
24 changes: 18 additions & 6 deletions t/01_client.t
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ subtest 'live' => sub {
};
ok client->run(qw[login atperl.bsky.social qbhd-opac-arvg-j7ol]), 'login ... ...';
ok client->run(qw[tl]), 'timeline';
like is_say { client->run(qw[tl --json]) }, qr[^{], 'timeline --json';
like is_say { client->run(qw[tl --json]) }, qr[^\[\{], 'timeline --json';
like is_say { client->run(qw[show-profile]) }, qr[atperl.bsky.social], 'show-profile';
like is_say { client->run(qw[show-profile --json]) }, qr[^{], 'show-profile --json';
like is_say { client->run(qw[show-profile --handle sankor.bsky.social]) }, qr[sankor.bsky.social], 'show-profile --handle sankor.bsky.social';
Expand All @@ -105,15 +105,15 @@ subtest 'live' => sub {
like is_say { client->run(qw[show-profile --json -H sankor.bsky.social]) }, qr["sankor], 'show-profile --json -H sankor.bsky.social';
subtest 'follows' => sub {
like is_say { client->run(qw[follows]) }, qr[atproto.com], 'follows';
like is_say { client->run(qw[follows --json]) }, qr[^{], 'follows --json';
like is_say { client->run(qw[follows --json]) }, qr[^\[\{], 'follows --json';
like is_say { client->run(qw[follows --handle sankor.bsky.social]) }, qr[atproto.com], 'follows --handle sankor.bsky.social';
like is_say { client->run(qw[follows --json --handle sankor.bsky.social]) }, qr["bsky.app"], 'follows --json --handle sankor.bsky.social';
like is_say { client->run(qw[follows --json -H sankor.bsky.social]) }, qr["bsky.app"], 'follows --json -H sankor.bsky.social';
};
subtest 'followers' => sub { # These tests might fail! I cannot control who follows the test account
my $todo = todo 'I cannot control who follows the test account';
like is_say { client->run(qw[followers]) }, qr[deal.bsky.social], 'followers';
like is_say { client->run(qw[followers --json]) }, qr[^{], 'followers --json';
like is_say { client->run(qw[followers --json]) }, qr[^\[\{], 'followers --json';
like is_say { client->run(qw[followers --handle sankor.bsky.social]) }, qr[atproto.com], 'followers --handle sankor.bsky.social';
like is_say { client->run(qw[followers --json --handle sankor.bsky.social]) }, qr["bsky.app"],
'followers --json --handle sankor.bsky.social';
Expand All @@ -124,16 +124,20 @@ subtest 'live' => sub {
if is_say { client->run(qw[follows]) } =~ qr[sankor.bsky.social];
skip_all 'sankor.bsky.social is blocked and cannot be followed; might be a race condition with another smoker'
if is_say { client->run(qw[blocks]) } =~ qr[sankor.bsky.social];
sleep 1;
like is_say { client->run(qw[follow sankor.bsky.social]) }, qr[at://did:plc:pwqewimhd3rxc4hg6ztwrcyj/app.bsky.graph.follow],
'follow sankor.bsky.social';
sleep 1;
like is_say { client->run(qw[follows]) }, qr[sankor.bsky.social], 'follows';
sleep 1; # sometimes the service has to catch up
like is_say { client->run(qw[unfollow sankor.bsky.social]) }, qr[at://did:plc:pwqewimhd3rxc4hg6ztwrcyj/app.bsky.graph.follow],
'unfollow sankor.bsky.social';
sleep 1;
unlike is_say { client->run(qw[follows]) }, qr[sankor.bsky.social], 'follows';
sleep 1; # sometimes the service has to catch up
like is_say { client->run(qw[follow did:plc:2lk3pbakx2erxgotvzyeuyem]) },
qr[at://did:plc:pwqewimhd3rxc4hg6ztwrcyj/app.bsky.graph.follow], 'follow did:plc:2lk3pbakx2erxgotvzyeuyem';
sleep 1; # sometimes the service has to catch up
like is_say { client->run(qw[follows]) }, qr[sankor.bsky.social], 'follows';
sleep 1; # sometimes the service has to catch up
like is_say { client->run(qw[unfollow did:plc:2lk3pbakx2erxgotvzyeuyem]) },
Expand All @@ -149,8 +153,10 @@ subtest 'live' => sub {
if is_say { client->run(qw[blocks]) } =~ qr[sankor.bsky.social];

#~ skip_all 'testing!';
like is_say { client->run(qw[block sankor.bsky.social]) }, qr[at://did:plc:pwqewimhd3rxc4hg6ztwrcyj/app.bsky.graph.block],
'block sankor.bsky.social';
todo 'service might be low updating profile info...' => sub {
like is_say { client->run(qw[block sankor.bsky.social]) }, qr[at://did:plc:pwqewimhd3rxc4hg6ztwrcyj/app.bsky.graph.block],
'block sankor.bsky.social';
};
sleep 1; # sometimes the service has to catch up
like is_say { client->run(qw[blocks]) }, qr[sankor.bsky.social], 'blocks';
like is_say { client->run(qw[unblock sankor.bsky.social]) }, qr[at://did:plc:pwqewimhd3rxc4hg6ztwrcyj/app.bsky.graph.block],
Expand All @@ -159,6 +165,12 @@ subtest 'live' => sub {
subtest 'post/delete' => sub {
like my $uri = is_say { client->run(qw[post Demo]) }, qr[at://did:plc:pwqewimhd3rxc4hg6ztwrcyj/app.bsky.feed.post], 'post Demo';
sleep 1; # sometimes the service has to catch up
ok client->run( 'like', $uri ), 'like at://...';
sleep 1;
like is_say { client->run( 'likes', $uri ) }, qr[atperl.bsky.social], 'likes at://...';
sleep 1;
ok client->run( 'like', $uri ), 'like at://...';
sleep 1;
ok client->run( 'delete', $uri ), 'delete at://...';
};
like is_say { client->run(qw[thread at://did:plc:qdvyf5jhuxqx667ay7k7nagl/app.bsky.feed.post/3kju327qezs2n]) },
Expand All @@ -168,7 +180,7 @@ subtest 'live' => sub {
like is_say { client->run(qw[list-app-passwords]) }, qr[Test Suite - bsky], 'list-app-passwords';
like is_say { client->run(qw[list-app-passwords --json]) }, qr[^\[\{], 'list-app-passwords --json';
like is_say { client->run(qw[notifications]) }, qr[did:plc:pwqewimhd3rxc4hg6ztwrcyj], 'notifications';
like is_say { client->run(qw[notifications --json]) }, qr[^{], 'notifications --json';
like is_say { client->run(qw[notifications --json]) }, qr[^\[\{], 'notifications --json';
like is_say { client->run(qw[show-session]) }, qr[did:plc:pwqewimhd3rxc4hg6ztwrcyj], 'show-session';
like is_say { client->run(qw[show-session --json]) }, qr[^{], 'show-session --json';
}
Expand Down

0 comments on commit 155df62

Please sign in to comment.