use v6.d;
use Cro::HTTP::Server;
use Cro::HTTP::Router;
use Cro::HTTP::Client;
use Cro::Uri::HTTP;
use XML;
use XML::XPath;
use MIME::Base64;
class VlcXMLParser does Cro::BodyParser {
method is-applicable(Cro::HTTP::Message $message --> Bool) {
with $message.content-type {
.type eq 'application'|'text' && .subtype eq 'xml' || .suffix eq 'json'
}
else {
False
}
}
method parse(Cro::HTTP::Message $message --> Promise) {
Promise(
supply {
my $payload = Blob.new;
whenever $message.body-byte-stream -> $blob {
$payload ~= $blob;
LAST emit from-xml($payload.decode('utf-8'));
}
}
)
}
}
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)
}
sub call-vlc(Str $path, *%args) {
my Cro::HTTP::Client $vlc .= new(
auth => { :username(), :password('ginopino') },
add-body-parsers => [ VlcXMLParser ],
);
state Cro::Uri::HTTP $base-uri .= parse('http://192.168.1.111:8080/requests/');
return $vlc.get(
$base-uri.add($path).add-query(|%args)
);
}
sub vlc-command(Str $command, *%args) {
return call-vlc('status.xml', :$command, |%args);
}
sub vlc-status() {
my $res = await call-vlc('status.xml');
my XML::Document $status = await $res.body;
return Promise.kept({:status(xml-to-hash($status.root))})
}
my $application = route {
get -> { static 'vlc.html' }
post -> 'play' { await vlc-command('pl_play') }
post -> 'pause' { await vlc-command('pl_pause') }
post -> 'stop' { await vlc-command('pl_stop') }
get -> 'status' {
my $status = await vlc-status();
content 'application/json', $status;
}
};
my Cro::Service $service = Cro::HTTP::Server.new(
:port(8080), :$application,
);
$service.start;
react whenever signal(SIGINT) {
$service.stop;
exit;
}