#!/usr/bin/env perl
#
-# Copyright © 2019 Nick Bowler
+# Copyright © 2019-2020 Nick Bowler
#
# Replace the current MPD play queue with a saved playlist, by rearranging
# existing queue entries when possible. This avoids losing the current
decode_argv(Encode::FB_CROAK);
binmode(STDOUT, ":utf8");
-use IO::Socket::INET6;
-use IO::Socket::UNIX;
use Getopt::Long qw(:config gnu_getopt);
-my $host = $ENV{MPD_HOST} // "localhost";
-my $port = $ENV{MPD_PORT} // 6600;
-my $sock;
-
-# Quotes the argument so that it is presented as a single argument to MPD
-# at the protocol level.
-sub escape {
- my $s = @_[0] // $_;
-
- # No way to encode literal newlines in the protocol, so we
- # convert any newlines in the arguments into a space, which
- # can help with quoting.
- $s =~ s/\n/ /g;
+use FindBin;
+use lib "$FindBin::Bin";
+use MPDHacks;
- if (/[ \t\\"]/) {
- $s =~ s/[\\"]/\\$&/g;
- return "\"$s\"";
- }
-
- $s =~ s/^\s*$/"$&"/;
- return $s;
-}
+my $sock;
# Submit a command to the MPD server; each argument to this function
# is quoted and sent as a single argument to MPD.
sub mpd_exec {
- my $cmd = join(' ', map { escape } @_);
+ my $cmd = join(' ', map { MPD::escape } @_);
print $sock "$cmd\n";
}
while (<$sock>) {
last if /^OK/;
die($_) if /^ACK/;
-
+
if (/^(\w+): (.*)$/) {
if ($1 eq "file") {
if (exists($matches{$2})) {
}
GetOptions(
- 'host|h=s' => \$host,
- 'port|p=s' => \$port,
+ 'host|h=s' => \$MPD::host,
+ 'port|p=s' => \$MPD::port,
'V|version' => sub { print_version(); exit },
'H|help' => sub { print_help(); exit },
print_usage(); exit 1
};
-# Connect to MPD.
-if ($host =~ /^[@\/]/) {
- $host =~ s/^@/\0/;
- $sock = new IO::Socket::UNIX(Type => SOCK_STREAM(), Peer => $host);
-} else {
- $sock = new IO::Socket::INET6(PeerAddr => $host,
- PeerPort => $port,
- Proto => 'tcp');
-}
-$sock or die "failed to connect to MPD: $!";
-binmode($sock, ":utf8");
-
-if (!(<$sock> =~ /^OK MPD ([0-9]+)\.([0-9]+)\.([0-9]+)$/)) {
- die "MPD failed to announce version: $!";
-}
+$sock = MPD::connect();
# Retrieve the current play queue and target play queue.
my $current = get_tracks_in_play_queue();