use v6.d;
use DB::SQLite;
use ScanDir;
use Vlc::Client;
use Lirc::Client;
use Lirc::Commands;
use App::MediaControl::DB;
use App::MediaControl::Web;
class App::MediaControl {
has $.config is required;
has Vlc::Client $!vlc;
has Lirc::Client $!lirc-client;
has Lirc::Commands $!lirc;
has App::MediaControl::DB $!db;
has App::MediaControl::Web $!web;
submethod TWEAK {
$!vlc .= new(
password => $!config<vlc><password>,
base-uri => $!config<vlc><base-uri>,
mrl-root => $!config<media><root>,
);
$!lirc-client .= new();
$!lirc .= new(client=>$!lirc-client);
$!db .= new(
pool => DB::SQLite.new(
filename => $!config<db><filename>,
busy-timeout => 20_000,
),
);
$!web .= new(
port => $!config<server><port>,
:$!vlc, :$!lirc, :$!db,
);
}
method !start-scan() {
my $root = $.config<media><root>;
$!db.clear-seen();
my Supplier $to-add .= new;
start react {
whenever scan-dir($root) -> $item {
when $item ~~ $root {}
when $item ~~ ScanDir::End {
$!db.remove-unseen();
$to-add.done();
$to-add = Nil;
}
my $path = $item.parent.relative($root);
$path = '' if $path eq '.';
my $name = $item.basename;
if !$item.e {
$!db.remove-entry(:$path,:$name);
}
else {
my $is-dir = $item.d;
with $to-add {
.emit(%(:$path,:$name,:$is-dir));
}
else {
$!db.add-entries([%(:$path,:$name,:$is-dir)]);
}
}
}
whenever $to-add.Supply.batch(:100elems,:2seconds) -> $items {
$!db.add-entries($items);
}
}
}
method start() {
$!db.ensure-schema();
self!start-scan();
$!web.start();
}
method stop() {
$!web.stop();
}
}