Initial commit
This commit is contained in:
174
YTMusicAPI/YTMusic.pm
Normal file
174
YTMusicAPI/YTMusic.pm
Normal file
@@ -0,0 +1,174 @@
|
||||
package YTMusicAPI::YTMusic;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Moose;
|
||||
with 'YTMusicAPI::Mixins::SearchMixin';
|
||||
|
||||
use JSON;
|
||||
use LWP::UserAgent;
|
||||
use HTTP::Cookies;
|
||||
use URI::Escape;
|
||||
use Encode qw(encode_utf8);
|
||||
use Data::Dumper;
|
||||
|
||||
use YTMusicAPI::Constants qw(
|
||||
$SUPPORTED_LANGUAGES
|
||||
$SUPPORTED_LOCATIONS
|
||||
USER_AGENT
|
||||
YTM_BASE_API
|
||||
YTM_DOMAIN
|
||||
YTM_PARAMS
|
||||
YTM_PARAMS_KEY
|
||||
);
|
||||
|
||||
use YTMusicAPI::Helpers;
|
||||
use YTMusicAPI::Parsers::Parser;
|
||||
use YTMusicAPI::Auth::AuthTypes;
|
||||
|
||||
sub new {
|
||||
my ( $class, $args ) = @_;
|
||||
my $self = {
|
||||
auth => $args->{auth} // undef,
|
||||
user => $args->{user} // undef,
|
||||
requests_session => $args->{requests_session} // 1,
|
||||
proxies => $args->{proxies} // undef,
|
||||
language => $args->{language} // 'en',
|
||||
location => $args->{location} // '',
|
||||
oauth_credentials => $args->{oauth_credentials} // undef,
|
||||
_base_headers => undef,
|
||||
_headers => undef,
|
||||
_input_dict => undef,
|
||||
_token => undef,
|
||||
_session => undef,
|
||||
_proxies => undef,
|
||||
};
|
||||
|
||||
bless $self, $class;
|
||||
|
||||
$self->{auth_type} = AuthType::UNAUTHORIZED;
|
||||
|
||||
if ( UNIVERSAL::isa( $self->{requests_session}, "LWP::UserAgent" ) ) {
|
||||
$self->{_session} = $self->{requests_session};
|
||||
}
|
||||
elsif ( $self->{requests_session} ) {
|
||||
$self->{_session} = LWP::UserAgent->new;
|
||||
}
|
||||
|
||||
$self->{cookies} = "SOCS=CAI";
|
||||
|
||||
$self->{context} = initialize_context();
|
||||
$self->{context}{"context"}{"client"}{"hl"} = "en";
|
||||
|
||||
$self->{parser} = YTMusicAPI::Parsers::Parser->new();
|
||||
|
||||
if ( $self->{user} ) {
|
||||
$self->{context}{'context'}{'user'}{'onBehalfOfUser'} = $self->{user};
|
||||
}
|
||||
|
||||
$self->{params} = YTM_PARAMS;
|
||||
if ( $self->{auth_type} == AuthType::BROWSER ) {
|
||||
$self->{params} .= YTM_PARAMS_KEY;
|
||||
}
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub base_headers {
|
||||
my ($self) = @_;
|
||||
|
||||
if ( !$self->{_base_headers} ) {
|
||||
if ( $self->{auth_type} == AuthType::BROWSER
|
||||
or $self->{auth_type} == AuthType::OAUTH_CUSTOM_FULL )
|
||||
{
|
||||
$self->{_base_headers} = $self->{_input_dict};
|
||||
}
|
||||
else {
|
||||
$self->{_base_headers} = {
|
||||
"user-agent" => USER_AGENT,
|
||||
"accept" => "*/*",
|
||||
"accept-encoding" => "gzip, deflate",
|
||||
"content-type" => "application/json",
|
||||
"content-encoding" => "gzip",
|
||||
"origin" => YTM_DOMAIN,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return $self->{_base_headers};
|
||||
}
|
||||
|
||||
sub headers {
|
||||
my ($self) = @_;
|
||||
|
||||
if ( !$self->{_headers} ) {
|
||||
$self->{_headers} = $self->base_headers();
|
||||
}
|
||||
|
||||
if ( $self->{auth_type} == AuthType::BROWSER ) {
|
||||
$self->{_headers}{'authorization'} =
|
||||
get_authorization( $self->{sapisid} . ' ' . $self->{origin} );
|
||||
}
|
||||
elsif ( $self->{auth_type} != AuthType::OAUTH_CUSTOM_FULL ) {
|
||||
|
||||
# $self->{_headers}{'authorization'} = $self->{_token}->as_auth();
|
||||
$self->{_headers}{'X-Goog-Request-Time'} = '' . time();
|
||||
}
|
||||
|
||||
return $self->{_headers};
|
||||
}
|
||||
|
||||
sub _send_request {
|
||||
my ( $self, $url, $body, $additionalParams ) = @_;
|
||||
$additionalParams //= "";
|
||||
|
||||
@$body{ keys %{ $self->{context} } } = values %{ $self->{context} };
|
||||
|
||||
if ( $self->{_headers} and !exists $self->{_headers}{'X-Goog-Visitor-Id'} )
|
||||
{
|
||||
my $visitor_id = get_visitor_id( $self->{_send_get_request} );
|
||||
$self->{_headers}{'X-Goog-Visitor-Id'} = %$visitor_id;
|
||||
}
|
||||
|
||||
$self->{_headers}{'Cookie'} = $self->{cookies};
|
||||
|
||||
my $request = HTTP::Request->new(
|
||||
POST => YTM_BASE_API . $url . $self->{params} . $additionalParams );
|
||||
my $headers = $self->headers();
|
||||
|
||||
foreach my $header_name ( keys %$headers ) {
|
||||
$request->header( $header_name => $headers->{$header_name} );
|
||||
}
|
||||
|
||||
$request->content( encode_json($body) );
|
||||
my $response = $self->{_session}->request($request);
|
||||
|
||||
if ( !$response->is_success ) {
|
||||
my $message = "Server returned HTTP " . $response->code . ".\n";
|
||||
my $error = $response->message;
|
||||
die $message . $error;
|
||||
}
|
||||
|
||||
return decode_json( $response->decoded_content );
|
||||
}
|
||||
|
||||
sub _send_get_request {
|
||||
my ( $self, $url, $params ) = @_;
|
||||
|
||||
my $response =
|
||||
$self->{_session}
|
||||
->get( $url, $self->{_headers} ? $self->headers() : $self->base_headers(),
|
||||
);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
sub _check_auth {
|
||||
my ($self) = @_;
|
||||
unless ( $self->{auth} ) {
|
||||
die "Please provide authentication before using this function";
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
Reference in New Issue
Block a user