#!/usr/bin/perl package mp3vk_api; use strict; use warnings; use Env qw(HOME); use utf8; use Encode; use URI::Escape; use HTML::Entities; use LWP; use LWP::Protocol::https; use LWP::Simple; use Parallel::ForkManager; our $VERSION = 0.2; #constructor sub new { my ($class, %args) = @_; return ('Error in syntax usage') if(_arg_validation(\%args) != 1); my $self = { ua => _mk_ua(), login => $args{login}, password => $args{password}, dir =>$args{dir}, threads=>30, }; bless $self, $class; die ('ERROR WITH CONNECTION AUTH') if($self->_connection_try() != 1); return $self; } #Creation of user agent. Private method sub _mk_ua { my $ua = LWP::UserAgent->new(); push @{ $ua->requests_redirectable }, 'POST'; $ua->cookie_jar( {} ); return ($ua); } #public method. search via vk. sub search { my ($self, $query) = @_; my $res = $self->{ua}->get('http://vk.com/search?c[section]=audio&c[q]='.uri_escape_utf8($query)); eval{$res->is_success;} or return 'Error possible with LWP_ua see err msg -> '.$res->status_line; # my @findnings = $res->decoded_content =~ m'(.*?)
'sgi; my @dump; push @dump, $self->_cleanup_response($_) for(@findnings); @dump = grep { defined $_ } @dump; return (\@dump); } #parsing of vk response. private method sub _cleanup_response { my ($self, $str) = @_; my ($title) = $str =~ m{(.*?)}si; return undef unless $title; $title =~ s/(<.*?>|\(.+\)|\&\w+|[;'"])//g; $title =~ s/\s+/ /g; $title = decode_entities($title); my ($duration) = $str =~ m{
(\d+:\d+)
}i; my ($link) = $str =~ m{value="(http://[^'"`]+\.mp3)}i; $duration = 0 unless($duration); return { title => $title, duration => $duration, link => $link }; } #check posibility of connection sub _connection_try{ my $self = shift; my $res = $self->{ua}->post('https://login.vk.com/?act=login', { email => $self->{login}, pass => $self->{password}, }); if( $res->is_success && ($res->decoded_content =~ /var\s+vk\s*=\s*\{[^\{\}]*?id\s*\:\s*(\d+)/i || $res->decoded_content =~ m#login\.vk\.com/\?act=logout#i ) ) { $self->{id} = $1; return 1; } return 0; } #validation of login and passwd sub _arg_validation { my $args = shift; unless (defined $args->{dir}){ $args->{dir} = "$ENV{HOME}/vk_music/"; mkdir $args->{dir}; } else{ $args->{dir} = "$ENV{HOME}/vk_music/$args->{dir}/"; mkdir $args->{dir}; } unless(defined $args->{login} && defined $args->{password} && $args->{login} =~ /^.*?\@.*?$/ && $args->{password} =~ /\w{2,}/){ return 0; } else{ return 1; } } sub vk_download{ my $self = shift; my $ref_dump = shift; my $pm = Parallel::ForkManager->new($self->{threads}); foreach (@{$ref_dump}) { $pm->start and next; # do the fork if (getstore($_->{link}, "$self->{dir}/$_->{title}.mp3") != RC_OK){ print 'error occured '."\n"; } else{ print $_->{title}.'.................. downloaded'."\n"; } $pm->finish; # do the exit in the child process } } 1;