Add .lrrignore support for filtering archives - #1672
Conversation
|
I forgot to handle escaped special characters in ignore rules. Maybe I should only implement a subset of gitignore instead. |
|
@Difegue this PR is ready for review. The syntax has been simplified and I've tested some common use cases in docker. |
7a862fb to
c9c6463
Compare
| $_ = create_path($_); | ||
| return if -d $_; #Directories are excluded on the spot | ||
|
|
||
| update_ignore_rules( dirname($_), $ignore_rules ); |
There was a problem hiding this comment.
Re-updating the rules for every single incoming file feels overkill.
I think we could get by only updating the rules when Shinobu gets started.
There was a problem hiding this comment.
Loading all .lrrignore files at startup would mean walking the filesystem twice: once to gather ignore rules, once to update filemaps.
Since find_path visits files in the same directory sequentially, update_ignore_rules can be simplified to a single string comparison for most calls:
return if $rules->{current_dir} && $rules->{current_dir} eq $dst_dir;BTW, File::Find supports pruning to skip ignored directories, but Win32::LongPath::Find lacks this functionality so I did not implement pruning.
And Win32::LongPath::Find does not return directories, meaning we can't only update rules when entering a directory.
| unless ( -d $name ) { | ||
|
|
||
| my $dirname = LANraragi::Model::Config->get_userdir; | ||
| my $ignore_rules = build_ignore_rules( $dirname, $name ); |
There was a problem hiding this comment.
This can be optimized by caching all ignore rules after the filemap scan. So any modifications made by the user will not take effect until Shinobu is restarted.
And newly added files can simply use the cached rules, no extra filesystem api calls are needed.
There was a problem hiding this comment.
Couple questions/issues from me at first look
I think ignore reads are cheap compared to ID compute, shinobu can probably do a read once before every scan. Upload API on the other hand is less forgiving (maybe cache the rules in redis? but ehh)
Otherwise, users should not expect to update rules during LRR uptime, bc the results will be inconsistent per worker (unless you're reading per call).
| @@ -154,14 +166,22 @@ sub update_filemap { | |||
| my @deletedfiles = grep { !$fshash{$_} } @filemapfiles; | |||
There was a problem hiding this comment.
All the ignored files are treated as deleted? What happens to metadata during a cleanup?
| if ( -e $deletedfile ) { | ||
| my $id = $redis->hget( "LRR_FILEMAP", $deletedfile ); | ||
| if ($id) { | ||
| $redis_arc->hset( $id, "file", "" ); |
There was a problem hiding this comment.
related (since "file" is false now):
LANraragi/lib/LANraragi/Utils/Database.pm
Line 391 in b94e480
There was a problem hiding this comment.
It seems ok in my test. delete_archive will not delete the actual file since the file field was wiped, only metadata will be deleted.
# lib/LANraragi/Model/Archive.pm +426
if ( -e $filename ) {
my $status = unlink_path($filename);|
OK, let me rethink the design:
So I should construct ignore rules only at startup, and cache them internally in ignore.pm. (but is it ok to make ignore.pm stateful? or simply put them in redis?) |
|
UPDATE:
|
This PR add
.lrrignoresupport with plexignore based syntax, triggered during Shinobu scanning and when new files are added.See #1120
syntax
Based on the Plex
.plexignorespec, extended with some useful features from gitignore:*/#\#escapes to literal#)!\!escapes to literal!)/.lrrignorefile's directory/\**\\X, the backslash is silently dropped (\X→X)Rules are resolved relative to the
.lrrignorefile's own directory, with nested rules overriding parent ones.interface
Ignore.pmexports four methods:is_ignored($file, $rules): walks parent directories viadirnameand matches against compiled regex rulesbuild_ignore_rules($content_dir): scans the directory tree for.lrrignorefiles and builds a rule setinitialize(): called at server startup, builds rules and stores them in Redis asLRR_IGNORE_RULESload_ignore_rules(): loads the frozen rule set from Redis withstate $cachedwindows compatibility
The project's existing cross-platform filesystem APIs don't quite cover some of the path operations this feature needs. I'm not familiar with Windows, so I can't say for sure it'll work there. The tests pass under MSYS2. And that is all I can guaranteen.
unit test
Added tests covering the various ignore syntax rules.