aboutsummaryrefslogtreecommitdiff
path: root/lib/Vlc/Client.rakumod
blob: 0860df43070b3fea804e3cc19459dccdc0c2bf02 (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
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);
    }
}