use v6.d.PREVIEW; need Ultramarine::Model::DirScanner; class Ultramarine::Model::Collection { has $.db is required handles ; has $.dirscan is required; has $.file-class is required; method new(|c) { my $self = self.bless(|c); start $self.update(); return $self; } has Promise $.is-ready .= new; has $!mark-ready = $!is-ready.vow; method update() { # I don't know what to do when things go wrong, let's "log" # it, at least CATCH { default { .perl.say } } react whenever $.dirscan.scan -> $path { when $path ~~ Ultramarine::Model::DirScanner::EndOfScan { # we use this to check that all the files in # the db have been seen, and delete those that haven't $.db.remove-unseen-files(); $!mark-ready.keep(True); } when $path ~~ IO::Path & :f { my $mtime = $path.modified.floor; # we only care to keep track of which files we've # seen during the initial scan (so we can clean up # rows for files that were removed while we were # not running); after that, we'll get notification # of deleted files, and we'll remove those $.db.seen-file(:$path) unless $.is-ready.status ~~ Kept; unless $.db.is-up-to-date(:$path,:$mtime) { my %metadata = $.file-class.new(:$path).metadata; $.db.ensure-song(:$path,:$mtime,:%metadata) if %metadata.keys; } } when $path ~~ IO::Path & :!f { $.db.ensure-file-absent(:$path); } } } }