0

Wrong album cover uri fixed; include, exclude list support

This commit is contained in:
Kaimi
2015-06-26 19:16:34 +03:00
parent 57432dad85
commit 790b540b37
2 changed files with 119 additions and 23 deletions

View File

@@ -8,20 +8,28 @@ Origin of the script is the following article: http://kaimi.ru/2013/11/yandex-mu
```bat ```bat
ya.pl [-adkpt] [long options...] ya.pl [-adkpt] [long options...]
-p --playlist playlist id to download -p --playlist playlist id to download
-k --kind playlist kind (eg. ya-playlist, music-blog, music-partners, etc.) -k --kind playlist kind (eg. ya-playlist, music-blog,
-a --album album to download music-partners, etc.)
-t --track track to download (album id must be specified) -a --album album to download
-d --dir download path (current direcotry will be used by default) -t --track track to download (album id must be specified)
--proxy HTTP-proxy (format: 1.2.3.4:8888) -d --dir download path (current direcotry will be used by
default)
--proxy HTTP-proxy (format: 1.2.3.4:8888)
--exclude skip tracks specified in file
--include filter tracks specified in file
--debug print debug info during work --debug print debug info during work
--help print usage --help print usage
--include option presume 'only' prefix
--include and --exclude options use weak match i.e. ~/$term/
Example: Example:
ya.pl -p 123 -k ya-playlist ya.pl -p 123 -k ya-playlist
ya.pl -a 123 ya.pl -a 123
ya.pl -a 123 -t 321 ya.pl -a 123 -t 321
``` ```
For further assistance don't hesitate to ask for help in GitHub issues or on the blog: http://kaimi.ru For further assistance don't hesitate to ask for help in GitHub issues or on the blog: http://kaimi.ru

110
src/ya.pl
View File

@@ -1,6 +1,8 @@
use utf8;
use strict; use strict;
use warnings; use warnings;
use Encode qw/from_to/; use Encode qw/from_to decode/;
use Encode::Guess;
use File::Basename; use File::Basename;
use POSIX qw/strftime/; use POSIX qw/strftime/;
use YaHash; use YaHash;
@@ -50,6 +52,7 @@ my %req_modules =
); );
$\ = NL; $\ = NL;
binmode STDOUT, ':' . TARGET_ENC;
my @missing_modules; my @missing_modules;
for(@{$req_modules{ALL}}, IS_WIN ? @{$req_modules{WIN}} : @{$req_modules{NIX}}) for(@{$req_modules{ALL}}, IS_WIN ? @{$req_modules{WIN}} : @{$req_modules{NIX}})
@@ -78,10 +81,15 @@ my ($opt, $usage) = Getopt::Long::Descriptive::describe_options
['track|t:i', 'track to download (album id must be specified)'], ['track|t:i', 'track to download (album id must be specified)'],
['dir|d:s', 'download path (current direcotry will be used by default)', {default => '.'}], ['dir|d:s', 'download path (current direcotry will be used by default)', {default => '.'}],
['proxy=s', 'HTTP-proxy (format: 1.2.3.4:8888)'], ['proxy=s', 'HTTP-proxy (format: 1.2.3.4:8888)'],
['exclude=s', 'skip tracks specified in file'],
['include=s', 'filter tracks specified in file'],
[], [],
['debug', 'print debug info during work'], ['debug', 'print debug info during work'],
['help', 'print usage'], ['help', 'print usage'],
[], [],
['--include option presume \'only\' prefix'],
['--include and --exclude options use weak match i.e. ~/$term/'],
[],
['Example: '], ['Example: '],
["\t".basename(__FILE__) . ' -p 123 -k ya-playlist'], ["\t".basename(__FILE__) . ' -p 123 -k ya-playlist'],
["\t".basename(__FILE__) . ' -a 123'], ["\t".basename(__FILE__) . ' -a 123'],
@@ -102,14 +110,25 @@ if($opt->dir && !-d $opt->dir)
my ($whole_file, $total_size); my ($whole_file, $total_size);
my $ua = LWP::UserAgent->new(agent => AGENT, cookie_jar => new HTTP::Cookies, timeout => TIMEOUT); my $ua = LWP::UserAgent->new(agent => AGENT, cookie_jar => new HTTP::Cookies, timeout => TIMEOUT);
my $json_decoder = JSON::PP->new->utf8->pretty->allow_nonref; my $json_decoder = JSON::PP->new->utf8->pretty->allow_nonref->allow_singlequote;
$json_decoder->allow_singlequote(1); my @exclude = ();
my @include = ();
if($opt->proxy) if($opt->proxy)
{ {
$ua->proxy(['http', 'https'], 'http://' . $opt->proxy . '/'); $ua->proxy(['http', 'https'], 'http://' . $opt->proxy . '/');
} }
if($opt->exclude)
{
@exclude = read_file($opt->exclude);
}
if($opt->include)
{
@include = read_file($opt->include);
}
if($opt->album || ($opt->playlist && $opt->kind)) if($opt->album || ($opt->playlist && $opt->kind))
{ {
my @track_list_info; my @track_list_info;
@@ -147,6 +166,37 @@ if($opt->album || ($opt->playlist && $opt->kind))
for my $track_info_ref(@track_list_info) for my $track_info_ref(@track_list_info)
{ {
my $skip = 0;
for my $title(@exclude)
{
if($track_info_ref->{title} =~ /\Q$title\E/)
{
$skip = 1;
last;
}
}
if($skip)
{
info(INFO, 'Skipping: ' . $track_info_ref->{title});
next;
}
$skip = 1;
for my $title(@include)
{
if($track_info_ref->{title} =~ /\Q$title\E/)
{
$skip = 0;
last;
}
}
if($skip && $opt->include)
{
info(INFO, 'Skipping: ' . $track_info_ref->{title});
next;
}
if(!$track_info_ref->{title}) if(!$track_info_ref->{title})
{ {
info(ERROR, 'Track with non-existent title. Skipping...'); info(ERROR, 'Track with non-existent title. Skipping...');
@@ -160,13 +210,15 @@ if($opt->album || ($opt->playlist && $opt->kind))
fetch_track($track_info_ref); fetch_track($track_info_ref);
} }
info(OK, 'Done!');
} }
sub fetch_track sub fetch_track
{ {
my $track_info_ref = shift; my $track_info_ref = shift;
fix_encoding(\$track_info_ref->{title}); #fix_encoding(\$track_info_ref->{title});
$track_info_ref->{title} =~ s/\s+$//; $track_info_ref->{title} =~ s/\s+$//;
$track_info_ref->{title} =~ s/[\\\/:"*?<>|]+/-/g; $track_info_ref->{title} =~ s/[\\\/:"*?<>|]+/-/g;
@@ -223,13 +275,13 @@ sub download_track
} }
my $file_path = $opt->dir.'/'.$title.FILE_SAVE_EXT; my $file_path = $opt->dir.'/'.$title.FILE_SAVE_EXT;
if(open(F, '>', $file_path)) if(open(my $fh, '>', $file_path))
{ {
local $\ = undef; local $\ = undef;
binmode F; binmode $fh;
print F $whole_file; print $fh $whole_file;
close F; close $fh;
my $disk_data_size = -s $file_path; my $disk_data_size = -s $file_path;
@@ -320,7 +372,7 @@ sub get_album_tracks_info
return; return;
} }
fix_encoding(\$title); #fix_encoding(\$title);
info(INFO, 'Album title: ' . $title); info(INFO, 'Album title: ' . $title);
info(INFO, 'Tracks total: ' . $json->{pageData}->{trackCount}); info(INFO, 'Tracks total: ' . $json->{pageData}->{trackCount});
@@ -369,7 +421,7 @@ sub get_playlist_tracks_info
return; return;
} }
fix_encoding(\$title); #fix_encoding(\$title);
info(INFO, 'Playlist title: '.$title); info(INFO, 'Playlist title: '.$title);
info(INFO, 'Tracks total: '. $json->{pageData}->{playlist}->{trackCount}); info(INFO, 'Tracks total: '. $json->{pageData}->{playlist}->{trackCount});
@@ -453,7 +505,7 @@ sub create_track_entry
$talb = $track_info->{albums}->[0]->{title}; $talb = $track_info->{albums}->[0]->{title};
$tpe2 = $is_various ? GENERIC_TITLE : $track_info->{albums}->[0]->{artists}->[0]->{name}; $tpe2 = $is_various ? GENERIC_TITLE : $track_info->{albums}->[0]->{artists}->[0]->{name};
# 'Dummy' cover for post-process # 'Dummy' cover for post-process
$apic = $track_info->{albums}->[0]->{artists}->[0]->{cover}->{uri}; $apic = $track_info->{albums}->[0]->{coverUri};
$tyer = $track_info->{albums}->[0]->{year}; $tyer = $track_info->{albums}->[0]->{year};
} }
@@ -517,6 +569,11 @@ sub fetch_album_cover
my $mp3tags = shift; my $mp3tags = shift;
my $cover_url = $mp3tags->{APIC}; my $cover_url = $mp3tags->{APIC};
if(!$cover_url)
{
info(DEBUG, 'Empty cover url');
return;
}
# Normalize url # Normalize url
$cover_url =~ s/%%/${\(COVER_RESOLUTION)}/; $cover_url =~ s/%%/${\(COVER_RESOLUTION)}/;
@@ -597,3 +654,34 @@ sub progress_bar
$char x (($width-1) * $got / $total). '>', $char x (($width-1) * $got / $total). '>',
$got, $total, 100 * $got / +$total; $got, $total, 100 * $got / +$total;
} }
sub read_file
{
my $filename = shift;
if(open(my $fh, '<', $filename))
{
binmode $fh;
chomp(my @lines = <$fh>);
close $fh;
# Should I just drop this stuff and demand only utf8?
my $blob = join '', @lines;
my $decoder = Encode::Guess->guess($blob, 'utf8');
$decoder = Encode::Guess->guess($blob, 'cp1251') unless ref $decoder;
if(!ref $decoder)
{
info(ERROR, 'Can\'t detect ' . $filename . ' internal encoding');
return;
}
@lines = map($decoder->decode($_), @lines);
return @lines;
}
info(ERROR, 'Failed to open file ' . $opt->ignore);
return;
}