diff options
Diffstat (limited to 'vlc.raku')
-rw-r--r-- | vlc.raku | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/vlc.raku b/vlc.raku new file mode 100644 index 0000000..1e66776 --- /dev/null +++ b/vlc.raku @@ -0,0 +1,102 @@ +#!/usr/bin/env rakudo +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')); + } + + # if we had LibXML + + # my LibXML::PushParser $parser .= new(); + # + # whenever $message.body-byte-stream -> $blob { + # $parser.push($blob); + # $payload ~= $blob; + # LAST emit $parser.finish-push; + # } + } + ) + } +} + +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; +} |