Allow filtering on number of read pages (#917)

* add search by progress

* fix null to int comparison on progress
This commit is contained in:
WindyMadman 2023-12-07 15:54:40 +08:00
parent 16bea450a3
commit 79c569321f
3 changed files with 31 additions and 12 deletions

View File

@ -9,10 +9,10 @@ use Redis;
use Storable qw/ nfreeze thaw /;
use Sort::Naturally;
use LANraragi::Utils::Generic qw(split_workload_by_cpu);
use LANraragi::Utils::String qw(trim);
use LANraragi::Utils::Generic qw(split_workload_by_cpu);
use LANraragi::Utils::String qw(trim);
use LANraragi::Utils::Database qw(redis_decode redis_encode);
use LANraragi::Utils::Logging qw(get_logger);
use LANraragi::Utils::Logging qw(get_logger);
use LANraragi::Model::Archive;
use LANraragi::Model::Category;
@ -156,19 +156,29 @@ sub search_uncached {
# Specific case for pagecount searches
# You can search for galleries with a specific number of pages with pages:20, or with a page range: pages:>20 pages:<=30.
if ( $tag =~ /^pages:(>|<|>=|<=)?(\d+)$/ ) {
my $operator = $1;
my $pagecount = $2;
# Or you can search for galleries with a specific number of pages read with read:20, or any pages read: read:>0
if ( $tag =~ /^(read|pages):(>|<|>=|<=)?(\d+)$/ ) {
my $col = $1;
my $operator = $2;
my $pagecount = $3;
$logger->debug("搜索具有页面的ID $operator $pagecount");
$logger->debug("搜索具有页面的ID $operator $pagecount $col");
# If no operator is specified, we assume it's an exact match
$operator = "=" if !$operator;
# Change the column based off the tag searched.
# "pages" -> "pagecount"
# "read" -> "progress"
$col = $col eq "pages" ? "pagecount" : "progress";
# Go through all IDs in @filtered and check if they have the right pagecount
# This could be sped up with an index, but it's probably not worth it.
foreach my $id (@filtered) {
my $count = $redis_db->hget( $id, "pagecount" );
# Default to 0 if null.
my $count = $redis_db->hget( $id, $col ) || 0;
if ( ( $operator eq "=" && $count == $pagecount )
|| ( $operator eq ">" && $count > $pagecount )
|| ( $operator eq ">=" && $count >= $pagecount )
@ -406,10 +416,10 @@ sub sort_results {
# (If no tag, defaults to "zzzz")
my %tmpfilter = map { $_ => ( $redis->hget( $_, "tags" ) =~ m/.*${re}:(.*)(\,.*|$)/ ) ? $1 : "zzzz" } @filtered;
my @sorted = map { $_->[0] } # Map back to only having the ID
sort { ncmp( $a->[1], $b->[1] ) } # Sort by the tag
map { [ $_, lc( $tmpfilter{$_} ) ] } # Map to an array containing the ID and the lowercased tag
keys %tmpfilter; # List of IDs
my @sorted = map { $_->[0] } # Map back to only having the ID
sort { ncmp( $a->[1], $b->[1] ) } # Sort by the tag
map { [ $_, lc( $tmpfilter{$_} ) ] } # Map to an array containing the ID and the lowercased tag
keys %tmpfilter; # List of IDs
if ($sortorder) {
@sorted = reverse @sorted;

View File

@ -115,4 +115,12 @@ $search = qq(pages:>150);
do_test_search();
is( $ids[0], "e69e43e1355267f7d32a4f9b7f2fe108d2401ebg", qq(Pagecount search ($search)) );
$search = qq(read:10);
do_test_search();
is( $ids[0], "e69e43e1355267f7d32a4f9b7f2fe108d2401ebf", qq(Read search ($search)) );
$search = qq(read:<11, read:>9);
do_test_search();
is( $ids[0], "e69e43e1355267f7d32a4f9b7f2fe108d2401ebf", qq(Read search ($search)) );
done_testing();

View File

@ -7,6 +7,7 @@ The search bar in LANraragi tries to not be too dumb and will actively suggest t
If you want to queue multiple terms/tags, you have to use **commas** to separate them, much like how tags are entered in the metadata field when editing an archive.
You can mix both tags and a specific title in a search if you want.
You can search for galleries with a specific number of pages with `pages:20`, or with a page range: `pages:>20, pages:<=30`.
You can also search for galleries with a specific number of pages read with similar syntax, `read:20`, or with a range: `read:>20, read:<=30`.
You can also use the following special characters in a search: