use v6.d;
use Cro::HTTP::Client;
use Cro::Uri::HTTP;
use Cro::BodyParser::VlcXML;
use XML;
multi sub maybe-bool('true') { True }
multi sub maybe-bool('false') { False }
multi sub maybe-bool($x) { $x }
sub xml-to-hash(XML::Element $elem) {
if $elem.elements() -> @children {
return %( @children.map: { .name => xml-to-hash($_) } )
}
return maybe-bool($elem.contents().join('').trim)
}
class Vlc::Client {
has Cro::HTTP::Client $!vlc;
has Str $.password is required;
has Str $.base-uri = 'http://127.0.0.1:8080/requests/';
has IO::Path() $.mrl-root = '/';
method !call-vlc(Str:D $path, *%args) {
$!vlc ||= Cro::HTTP::Client.new(
auth => { :username(), :password(self.password) },
add-body-parsers => [ Cro::BodyParser::VlcXML ],
);
state Cro::Uri::HTTP $base-uri .= parse(self.base-uri);
return $!vlc.get(
$base-uri.add($path).add-query(|%args),
);
}
method command(Str:D $command, *%args) {
return self!call-vlc('status.xml', :$command, |%args);
}
method play-file(Str:D :$path!, Str:D :$name!) {
return self.command(
'in_play',
input => self.mrl-root.child($path).child($name),
);
}
method status() {
my $res = await self!call-vlc('status.xml');
my XML::Document $status = await $res.body;
return Promise.kept(xml-to-hash($status.root));
}
method playlist() {
my $res = await self!call-vlc('playlist.xml');
my XML::Document $playlist = await $res.body;
my @playlist-items = $playlist.elements()
.grep(*.attribs<name> eq 'Playlist').first
.elements().map(
-> $leaf {
%(
$leaf.attribs<name id duration uri>:p.Slip,
current => $leaf.attribs<current>:exists,
)
},
);
return Promise.kept(@playlist-items);
}
}