aboutsummaryrefslogtreecommitdiff
path: root/vlc.raku
blob: 1e667760cc724f88689109af3a67bb80e39b0db5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
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;
}