File Coverage

blib/lib/AnyEvent/DAAP/Server/Track.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             package AnyEvent::DAAP::Server::Track;
2 2     2   771 use Any::Moose;
  2         31807  
  2         14  
3 2     2   2055 use Net::DAAP::DMAP;
  0            
  0            
4              
5             # from Net::DAAP::Server::Track
6             our @Attributes = qw(
7             dmap_itemid dmap_itemname dmap_itemkind dmap_persistentid
8             daap_songalbum daap_songartist daap_songbitrate
9             daap_songbeatsperminute daap_songcomment daap_songcompilation
10             daap_songcomposer daap_songdateadded daap_songdatemodified
11             daap_songdisccount daap_songdiscnumber daap_songdisabled
12             daap_songeqpreset daap_songformat daap_songgenre
13             daap_songdescription daap_songrelativevolume daap_songsamplerate
14             daap_songsize daap_songstarttime daap_songstoptime daap_songtime
15             daap_songtrackcount daap_songtracknumber daap_songuserrating
16             daap_songyear daap_songdatakind daap_songdataurl
17             com_apple_itunes_norm_volume
18             daap_songgrouping daap_songcodectype daap_songcodecsubtype
19             com_apple_itunes_itms_songid com_apple_itunes_itms_artistid
20             com_apple_itunes_itms_playlistid com_apple_itunes_itms_composerid
21             com_apple_itunes_itms_genreid
22             dmap_containeritemid
23             );
24              
25             has dmap_itemid => (
26             is => 'rw',
27             isa => 'Int',
28             default => sub { 0+$_[0] & 0xFFFFFF },
29             );
30              
31             has $_, is => 'rw' for @Attributes;
32              
33             __PACKAGE__->meta->make_immutable;
34              
35             no Any::Moose;
36              
37             sub _dmap_field {
38             my ($self, $name) = @_;
39             $name =~ s/[.-]/_/g;
40             return $self->{$name};
41             }
42              
43             sub allow_range { 0 }
44              
45             sub stream {
46             my ($self, $connection, $req) = @_;
47             my ($response, $pos) = $self->parse_request($req);
48             $self->write_data($connection, $response, $pos);
49             }
50              
51             sub parse_request {
52             my ($self, $req) = @_;
53              
54             my $pos;
55              
56             if (my $range = $req->header('Range')) {
57             # To make things simple, assume Range: header is sent only as Range: bytes={start}-
58             if ($range =~ /^bytes=(\d+)-/) {
59             $pos = $1;
60             } elsif ($range) {
61             warn qq(Cannot handle range: '$range');
62             }
63             }
64              
65             my ($code, $message) = $pos ? ( 206, 'Partial Content' ) : ( 200, 'OK' );
66             my $res = HTTP::Response->new($code, $message, [ Connection => 'close' ]);
67             $res->header(Content_Range => "bytes $pos-/*") if $pos;
68             $res->header(Accept_Ranges => 'bytes') if $self->allow_range;
69              
70             return ($res, $pos);
71             }
72              
73             sub write_data {
74             my ($self, $connection, $res, $pos) = @_;
75              
76             my $data = $self->data($pos);
77             $res->content($data);
78             $res->content_length(length $data);
79             $self->push_response($connection, $res);
80             }
81              
82             sub data {
83             my ($self, $pos) = @_;
84             die 'implement $self->data() or override $self->write_data()';
85             # return $data;
86             }
87              
88             sub push_response {
89             my ($self, $connection, $res) = @_;
90             $connection->handle->push_write(
91             'HTTP/1.1 ' . $res->as_string("\r\n")
92             );
93             $connection->handle->push_shutdown;
94             }
95              
96             1;
97              
98             __END__