From 9ef40433a1ba4044561f5941b07ba0d90a085942 Mon Sep 17 00:00:00 2001 From: Ian Beckwith Date: Sat, 6 Nov 2010 22:39:10 +0000 Subject: [PATCH] id3fs-tag: -V: summarize tags in directories --- bin/id3fs-tag | 71 +++++++++++++++++++++++++++++++++++++++++----- lib/ID3FS/AudioFile.pm | 23 +++++++++++++++ lib/ID3FS/AudioFile/Mp3.pm | 10 ++----- 3 files changed, 89 insertions(+), 15 deletions(-) diff --git a/bin/id3fs-tag b/bin/id3fs-tag index 0b1f20e..6bff1c4 100755 --- a/bin/id3fs-tag +++ b/bin/id3fs-tag @@ -25,13 +25,15 @@ use vars qw($me); $me=($0=~/(?:.*\/)?(.*)/)[0]; my @extensions=qw(mp3); # FIXME: flac ogg +my (%argv_tags, %dir_tags, %file_tags); +my $current_argv; my $verbose=0; my $help=0; my ($artist, $album, $track, $tracknum, $year, $v1genre, $comment, $delete_artist, $delete_album, $delete_track, $delete_tracknum, $delete_year, $delete_v1genre, $delete_comment, $delete_all, $delete_genre, $genre, $add_tags, $delete_tags, $overwrite_tagvals, - $delete_tagvals); + $delete_tagvals, $tag_summary); Configure(qw(bundling no_ignore_case)); my $optret=GetOptions( @@ -58,6 +60,7 @@ my $optret=GetOptions( "overwrite-tagvals|tagvals|o=s" => \$overwrite_tagvals, "delete-tags|T=s" => \$delete_tags, "delete-tags-with-values|O=s" => \$delete_tagvals, + "summary|V" => \$tag_summary, ); usage() if(!@ARGV || !$optret || $help); @@ -69,9 +72,13 @@ while(my $path=shift @ARGV) warn("$me: $path: not found\n"); next; } + $current_argv=$path; # ick, global nastiness File::Find::find( {wanted => \&wanted, follow => 1, no_chdir => 1}, $path); } +summarize_tags() if($tag_summary); + + sub wanted { my $ext=''; @@ -80,16 +87,23 @@ sub wanted { my $file=ID3FS::AudioFile->new($_); return unless($file); - my $changes=0; - $changes = do_deletes($file); - $changes += do_adds($file); - if($changes) + if($tag_summary) { - do_write($file); + gather_tags($_, $file); } else { - do_display($file); + my $changes=0; + $changes = do_deletes($file); + $changes += do_adds($file); + if($changes) + { + do_write($file); + } + else + { + do_display($file); + } } } } @@ -189,6 +203,49 @@ sub do_display } } +sub gather_tags +{ + my($path, $file)=@_; + my @tags=$file->tags(); + @tags=map { join('/', grep { defined; } @$_); } @tags; + @tags=ID3FS::AudioFile::uniq(@tags); + $file_tags{$path}=\@tags; + my @argv_tags=(); + @argv_tags=@{$argv_tags{$current_argv}} if($argv_tags{$current_argv}); + $argv_tags{$current_argv}=[ ID3FS::AudioFile::uniq(@tags, @argv_tags) ]; +} + +sub summarize_tags +{ + my @all_tags=ID3FS::AudioFile::uniq(map { @$_; } values(%argv_tags)); + # find common tags + my @common_tags=(); +OUTER: for my $tag (@all_tags) + { + for my $taglist (values(%argv_tags)) + { + next OUTER unless(grep { $_ eq $tag; } @$taglist); + } + push(@common_tags, $tag); + } + print "ALL: ", join(', ', @all_tags), "\n"; + print "COMMON: ", join(', ', @common_tags), "\n"; + + use Data::Dumper; + # remove common tags from %argv_tags + for my $argv (keys(%argv_tags)) + { + next unless(@{$argv_tags{$argv}}); + $argv_tags{$argv}= [ ID3FS::AudioFile::list_remove(\@common_tags, $argv_tags{$argv}) ]; + } + + print "PER-DIR: \n"; + for my $argv (keys(%argv_tags)) + { + print "$argv: ", join(', ', @{$argv_tags{$argv}}), "\n"; + } +} + sub usage { die("Usage: $me [-vhALSNY0CDG] [-a ARTIST] [-l ALBUM] [-s SONG] [-n TRACKNUM] FILES...\n". diff --git a/lib/ID3FS/AudioFile.pm b/lib/ID3FS/AudioFile.pm index e020b43..ffd78d6 100644 --- a/lib/ID3FS/AudioFile.pm +++ b/lib/ID3FS/AudioFile.pm @@ -173,4 +173,27 @@ sub stripslashes return $text; } +# This location for these subs is pretty much arbitrary +sub uniq +{ + # class method + shift if(ref($_[0]) eq "ID3FS::AudioFile"); + my (@things)=@_; + my %hash=(); + @hash{@things}=(); + return(sort keys(%hash)); +} + +sub list_remove +{ + my($remove, $list)=@_; + return(()) unless($list && @$list); + my @list=@$list; + for my $tag (@$remove) + { + @list=grep { $_ ne $tag; } @list; + } + return(@list); +} + 1; diff --git a/lib/ID3FS/AudioFile/Mp3.pm b/lib/ID3FS/AudioFile/Mp3.pm index 7cd15b9..8ec87ef 100644 --- a/lib/ID3FS/AudioFile/Mp3.pm +++ b/lib/ID3FS/AudioFile/Mp3.pm @@ -18,6 +18,7 @@ package ID3FS::AudioFile::Mp3; use strict; use warnings; +use ID3FS::AudioFile; use MP3::Tag; use MP3::Info; @@ -145,7 +146,7 @@ sub add_tags my($self, @tags)=@_; my $existing=$self->tags(); my @existing=split(/\s*,\s*/, $existing) if($existing); - my @merged=$self->uniq(@tags, @existing); + my @merged=ID3FS::AudioFile::uniq(@tags, @existing); my $genre=join(', ', @merged); return($self->set("genre", $genre)); } @@ -301,13 +302,6 @@ sub delete } } -sub uniq -{ - my ($self, @things)=@_; - my %hash=(); - @hash{@things}=(); - return(sort keys(%hash)); -} sub channels { -- 2.11.0