From 491dc1aeab9b445ee28f972e19a1cbb4cb9f3af7 Mon Sep 17 00:00:00 2001 From: dakkar Date: Sat, 20 Jan 2024 17:30:25 +0000 Subject: look at fs on demand, don't watch it ScanDir (well, fs notifications in raku) is too slow to keep up with actual fs changes (especially when e.g. a file is being downloaded) there's actually no need to watch fs changes, we can just sync the db with the file system we look at each directory --- lib/App/MediaControl/Model.rakumod | 101 +++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 lib/App/MediaControl/Model.rakumod (limited to 'lib/App/MediaControl/Model.rakumod') diff --git a/lib/App/MediaControl/Model.rakumod b/lib/App/MediaControl/Model.rakumod new file mode 100644 index 0000000..6d1c771 --- /dev/null +++ b/lib/App/MediaControl/Model.rakumod @@ -0,0 +1,101 @@ +use v6.d; +use App::MediaControl::FS; +use App::MediaControl::DB; + +class App::MediaControl::Model { + has App::MediaControl::FS $.fs is required; + has App::MediaControl::DB $.db is required; + + method get-children-of($id) { + my @db-children = self.db.get-children-of($id); + # [{id,path,name,is_dir,watched_time}] + + my $path; + if (@db-children) { + $path = @db-children[0]; # they all have the same path + } elsif ($id.defined) { + my $entry = self.db.get-entry($id); + $path = "{$entry}{$entry}"; + } else { + $path = '/'; + } + + my @fs-children = self.fs.get-children-of($path); + # [{name,is_dir}] + + my ($db-idx, $fs-idx, $changed) = 0, 0, False; + + sub add-to-db() { + self.db.add-entry( + :$path, + name => @fs-children[$fs-idx], + is-dir => @fs-children[$fs-idx]., + ); + $changed=True; + ++$fs-idx; + } + sub remove-from-db() { + self.db.remove-entry(@db-children[$db-idx]); + $changed=True; + ++$db-idx; + } + + while ($db-idx < @db-children && $fs-idx < @fs-children) { + given @db-children[$db-idx] leg @fs-children[$fs-idx] { + when Order::Same { + ++$db-idx; ++$fs-idx; + } + + when Order::Less { + remove-from-db(); + } + + when Order::More { + add-to-db(); + } + } + } + + while ($db-idx < @db-children) { + remove-from-db(); + } + + while ($fs-idx < @fs-children) { + add-to-db(); + } + + if $changed { + @db-children = self.db.get-children-of($id); + } + + return @db-children; + } + + method get-parents-of(Int:D() $id) { + return self.db.get-parents-of($id); + } + + method get-entry(Int:D() $id) { + return self.db.get-entry($id); + } + + method mark-entry-watched(Int:D() $id) { + return self.db.mark-entry-watched($id); + } + + method get-recently-watched-folders(Int:D() $limit=20) { + my @db-folders = self.db.get-recently-watched-folders($limit); + my $changed = False; + for @db-folders -> $f { + next if self.fs.exists("{$f}{$f}"); + self.db.remove-entry($f); + $changed = True; + } + + if $changed { + @db-folders = self.db.get-recently-watched-folders($limit); + } + + return @db-folders; + } +} -- cgit v1.2.3