X-Git-Url: https://git.draconx.ca/gitweb/mpdhacks.git/blobdiff_plain/f0e74c3a1fc44153fe80961ff7de3b4a0786e5ea..HEAD:/mpdreload.pl diff --git a/mpdreload.pl b/mpdreload.pl index 66bb39d..8cf010d 100755 --- a/mpdreload.pl +++ b/mpdreload.pl @@ -26,6 +26,8 @@ use MPDHacks; my $sock; +my $pl_current_length; + # Returns a hash reference mapping filenames to an array reference listing # the queue IDs for that file in the current play queue. sub get_tracks_in_play_queue { @@ -48,6 +50,8 @@ sub get_tracks_in_play_queue { } } + $pl_current_length = $pos+1; + return (\%matches, \%idmap); } @@ -126,46 +130,74 @@ MPD::run("tagtypes", "clear"); my ($current, $idmap) = get_tracks_in_play_queue(); my $target = get_playlist_files($ARGV[0]); -my $end_position = (keys %$current); -my $num_added = 0; my $add_start; -sub load_tracks($) { - my ($seq) = @_; +sub load_tracks($$) { + my ($seq, $dst) = @_; + my ($newlen, $count); my $start = $add_start // $seq; + my $add_position = $pl_current_length; my $end = $seq+1; - my $add_position = $end_position; + $dst //= $start; + MPD::exec("load", $ARGV[0], "$start:$end"); - $end_position += $end - $start; - MPD::exec("move", "$add_position:$end_position", "$start") - if ($add_position != $start); + MPD::exec("status"); + MPD::exec("command_list_end"); + + while (<$sock>) { + last if (/^OK/); + die($_) if (/^ACK/); + + if (/^(\w+): (.*)$/) { + if ($1 eq "playlistlength") { + $newlen = int($2); + } + } + } + + $count = $newlen - $pl_current_length; + + MPD::exec("command_list_begin"); + if ($newlen > $pl_current_length) { + MPD::exec("move", "$add_position:$newlen", $dst) + if ($add_position != $dst); + } + $pl_current_length = $newlen; undef $add_start; + + return $count; } MPD::exec("command_list_begin"); +my ($num_added, $num_failed) = (0, 0); for (my $i = 0; $i < @$target; $i++) { my $f = $target->[$i]; my $id = shift @{ $current->{$f} }; - load_tracks($i - 1) if (defined $id and defined $add_start); + if (defined $id and defined $add_start) { + my $n = $i - $add_start; + my $m = load_tracks($i-1, $add_start - $num_failed); + + $num_added += $m; + $num_failed += $n - $m; + } if (defined $id) { # Try not to move tracks already in the right place. - MPD::exec("moveid", $id, $i) - if ($i != $idmap->{$id} + $num_added); + MPD::exec("moveid", $id, $i - $num_failed) + if ($i - $num_failed != $idmap->{$id} + $num_added); } else { $add_start //= $i; - $num_added++; } } # Now all unwanted tracks from the original playqueue have been moved to the # end and can be deleted all at once. -my $pos = $add_start // @$target; +my $pos = ($add_start // @$target) - $num_failed; MPD::exec("delete", $pos . ":") if map { @$_ } values %$current; MPD::exec("load", $ARGV[0], "$add_start:") if defined $add_start; MPD::run("command_list_end");