use v6.d.PREVIEW;
use Cro::HTTP::Router;
use Cro::HTTP::Request;
use Cro::HTTP::Response;
use Cro::Transform;
use Cro;
class Ultramarine::Controller {
has $.license is required;
has $.authorisation is required;
has $.collection is required;
sub respond(*@body) {
response.status = 200;
response.set-body(@body);
}
my class URLRewrite does Cro::Transform {
method consumes() { Cro::HTTP::Request }
method produces() { Cro::HTTP::Request }
my token prefix { '/rest' }
my token api-method { '/' \w+ }
my token suffix { '.view' }
my token query { '?' .* }
my token api-url { ^ <prefix> <api-method> <suffix>? <query> $ }
method transformer(Supply $requests --> Supply) {
supply whenever $requests -> $request {
with $request {
if (.target ~~ /<api-url>/) {
emit .clone(
original-target => .original-target // .target,
target => ($<api-url><prefix api-method query>).join,
);
}
else {
emit $_;
}
}
}
}
}
method inner-routes() {
return route {
before $!authorisation;
post my $ping = -> 'ping' { respond [] }
get $ping;
post my $getLicense = -> 'getLicense' {
my $expires = $.license.expires-at.DateTime.truncated-to('second');
respond [
:status<ok>,
license => [
:valid($.license.is-valid.Str.lc),
:email($.license.email),
:licenseExpires($expires.yyyy-mm-dd ~ ':' ~ $expires.hh-mm-ss),
],
],
}
get $getLicense;
post my $getMusicFolders = -> 'getMusicFolders' {
respond [
:status<ok>,
musicFolders => [
$.collection.top-folders.map:
{ musicFolder => [ id => $^d.id, name => $^d.name ] },
]
],
}
get $getMusicFolders;
post my $getIndexes = -> 'getIndexes', :$musicFolderId is query, :$ifModifiedSince is query {
await $.collection.is-ready;
my $indexes = $.collection.dir-children-of(id=>$musicFolderId)
.classify( *.name.substr(0,1).uc ).pairs.map: -> (:key($initial),:value($dirs)) {
index => [
name => $initial,
|($dirs.map: { artist => [ id => $^d.id, name => $^d.name ] })
]
};
my $songs = $.collection.songs-children-of(id=>$musicFolderId)
.map: -> $song {
my $c = [
id => $song.id,
path => $song.path,
isDir => 'false',
isVideo => 'false',
type => 'music',
contentType => 'audio/mpeg',
|($song.metadata<tags><album artist genre track title>:p),
year => $song.metadata<tags><date>,
bitRate => $song.metadata<bit_rate>.Int,
duration => ($song.metadata<duration>*60).Int,
suffix => $song.metadata<format_name>,
albumId => $song.album_id,
artistId => 1,
size => 10000,
created => Instant.from-posix($song.mtime).DateTime.Str,
];
warn $c.perl;
child => $c;
}
respond [
:status<ok>,
indexes => [
lastModified => now.to-posix[0].Int,
ignoredArticles => '',
|$indexes,
|$songs,
],
];
}
get $getIndexes;
get -> 'dakkarList' {
await $.collection.is-ready;
respond [
:status<ok>,
songs => $.collection.all-songs,
];
}
}
}
method routes() {
return Cro.compose(
URLRewrite,
route { include 'rest' => self.inner-routes() },
);
}
}