aboutsummaryrefslogtreecommitdiff
path: root/vlc.raku
diff options
context:
space:
mode:
Diffstat (limited to 'vlc.raku')
-rw-r--r--vlc.raku102
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;
+}