package WebService::8tracks; use Any::Moose; =pod =head1 NAME WebService::8tracks - Handle 8tracks API =head1 SYNOPSIS use WebService::8tracks; my $api = WebService::8tracks->new; # explore my $res = $api->mixes({ sort => 'recent' }); foreach my $mix (@{$res->{mixes}}) { print "$mix->{user}->{name} $mix->{name} id=$mix->{id}\n"; } # listen my $session = $api->create_session($res->{mixes}->[0]->{id}); my $res = $session->play; my $media_url = $res->{set}->{track}->{url}; ... $res = $session->next; $res = $session->skip; # authenticated API my $api = WebService::8tracks->new(username => ..., password => ...); $api->fav(23); # fav a track =head1 DESCRIPTION WebService::8tracks provides Perl interface to 8tracks API. Currently, all response objects are almost naive hashrefs. =cut has 'username', ( is => 'rw', isa => 'Str', ); has 'password', ( is => 'rw', isa => 'Str', ); has 'user_agent', ( is => 'rw', isa => 'LWP::UserAgent', default => sub { require LWP::UserAgent; return LWP::UserAgent->new; }, ); __PACKAGE__->meta->make_immutable; no Any::Moose; our $VERSION = '0.01'; use WebService::8tracks::Session; use WebService::8tracks::Response; use JSON::XS qw(decode_json); use URI::Escape qw(uri_escape uri_escape_utf8); use HTTP::Request; our @CARP_NOT = ( our @ISA, 'WebService::8tracks::Session' ); our $API_BASE_URL = 'http://8tracks.com/'; sub api_url { my ($self, $path, $qparam) = @_; my $url = "http://api.8tracks.com/$path.json"; if ($qparam) { if (ref $qparam eq 'HASH' && scalar keys %$qparam) { my @pairs; while (my ($key, $value) = each %$qparam) { my $pair = $key . '='; if (utf8::is_utf8 $value) { $pair .= uri_escape_utf8 $value; } else { $pair .= uri_escape $value; } push @pairs, $pair; } $url .= '?' . join '&', @pairs; } else { $url .= "?$qparam"; } } return $url; } sub request_api { my ($self, $method, $path, $qparam) = @_; my $url = $self->api_url($path, $qparam); my $req = HTTP::Request->new($method, $url); if ($method eq 'POST') { $req->header(Content_Length => 0); } if ($self->username && $self->password) { $req->authorization_basic($self->username, $self->password); } my $res = $self->user_agent->request($req); my $api_response = decode_json $res->content; return WebService::8tracks::Response->new($api_response); } =head1 METHODS =over 4 =item new my $api = WebService::8tracks->new([ username => ..., password => ... ]); Create API object. Pass username and password args to use methods that require login (like, fav, follow). =item mixes([ \%qparam ]) my $res = $api->mixes({ page => 2 }); my $res = $api->mixes({ q => 'miles davis' }); List mixes. =cut sub mixes { my ($self, $qparam) = @_; return $self->request_api(GET => 'mixes', $qparam); } =item user($id_or_name) my $res = $api->user(1); my $res = $api->user('remi'); View user info. =cut sub user { my ($self, $user, $qparam) = @_; return $self->request_api(GET => "users/$user", $qparam); } =item user_mixes($id_or_name[, \%qparam ]) my $res = $api->user_mixes(2); my $res = $api->user_mixes('dp', { view => 'liked' }); List mixes made by a user. =cut sub user_mixes { my ($self, $user, $qparam) = @_; return $self->request_api(GET => "users/$user/mixes", $qparam); } sub _create_play_token { my $self = shift; my $result = $self->request_api(GET => 'sets/new'); return $result->{play_token}; } =item create_session($mix_id) my $session = $api->create_session($mix_id); my $res = $session->play; my $res = $session->next; my $res = $session->skip; Start playing mix. Returns a WebService::8tracks::Session. =cut sub create_session { my ($self, $mix_id) = @_; return WebService::8tracks::Session->new( api => $self, play_token => $self->_create_play_token, mix_id => $mix_id, ); } =item like / unlike / toggle_like($mix_id) my $res = $api->toggle_like($mix_id); Like/unlike/toggle_like a mix. Requires username and password. =cut foreach my $like (qw(like unlike toggle_like)) { my $code = sub { my ($self, $mix_id) = @_; return $self->request_api(POST => "mixes/$mix_id/$like"); }; no strict 'refs'; *$like = $code; } =item fav / unfav / toggle_fav($track_id) my $res = $api->fav($track_id); Fav/unfav/toggle_fav a track. Requires username and password. =cut foreach my $fav (qw(fav unfav toggle_fav)) { my $code = sub { my ($self, $track_id) = @_; return $self->request_api(POST => "tracks/$track_id/$fav"); }; no strict 'refs'; *$fav = $code; } =item follow / unfollow / toggle_follow($user_id) my $res = $api->follow($user_id); Follow/unfollow/toggle_follow a user. Requires username and password. =cut foreach my $follow (qw(follow unfollow toggle_follow)) { my $code = sub { my ($self, $user_id) = @_; return $self->request_api(POST => "users/$user_id/$follow"); }; no strict 'refs'; *$follow = $code; } =back =cut 1; __END__ =head1 AUTHOR motemen Emotemen@gmail.comE =head1 SEE ALSO 8tracks Playback API. L =head1 LICENSE This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut