summaryrefslogtreecommitdiff
path: root/lib/VNWeb/Filters.pm
blob: 8fae51a8d97a9c8fdb7d4d7fe9e7317abb9652f3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package VNWeb::Filters;

# This module implements validating and querying the search filters. I'm not
# sure yet if this filter system will continue to exist in this form or if
# there will be a better advanced search system to replace it, but either way
# we'll need to support these filters for the forseeable future.

use VNWeb::Prelude;

my $VN = form_compile any => {
    date_before => { required => 0, rdate => 1 },
    date_after  => { required => 0, rdate => 1 },
    released    => { undefbool => 1 },
    length      => { required => 0, enum => \%VN_LENGTH },
    hasani      => { undefbool => 1 },
    hasshot     => { undefbool => 1 },
    tag_inc     => { undefarray => { id => 1 } },
    tag_exc     => { undefarray => { id => 1 } },
    taginc      => { undefarray => {} }, # [old] Tag search by name
    tagexc      => { undefarray => {} }, # [old] Tag search by name
    tagspoil    => { required => 0, default => 0, uint => 1, range => [0,2] },
    lang        => { undefarray => { enum => \%LANGUAGE } },
    olang       => { undefarray => { enum => \%LANGUAGE } },
    plat        => { undefarray => { enum => \%PLATFORM } },
    staff_inc   => { undefarray => { id => 1 } },
    staff_exc   => { undefarray => { id => 1 } },
    ul_notblack => { undefbool => 1 },
    ul_onwish   => { undefbool => 1 },
    ul_voted    => { undefbool => 1 },
    ul_onlist   => { undefbool => 1 },
};

my $RELEASE = form_compile any => {
    type        => { required => 0, enum => \%RELEASE_TYPE },
    patch       => { undefbool => 1 },
    freeware    => { undefbool => 1 },
    doujin      => { undefbool => 1 },
    uncensored  => { undefbool => 1 },
    date_before => { required => 0, rdate => 1 },
    date_after  => { required => 0, rdate => 1 },
    released    => { undefbool => 1 },
    minage      => { undefarray => { enum => \%AGE_RATING } },
    lang        => { undefarray => { enum => \%LANGUAGE } },
    olang       => { undefarray => { enum => \%LANGUAGE } },
    resolution  => { undefarray => {} },
    plat        => { undefarray => { enum => \%PLATFORM } },
    prod_inc    => { undefarray => { id => 1 } },
    prod_exc    => { undefarray => { id => 1 } },
    med         => { undefarray => { enum => \%MEDIUM } },
    voiced      => { undefarray => { enum => \%VOICED } },
    ani_story   => { undefarray => { enum => \%ANIMATED } },
    ani_ero     => { undefarray => { enum => \%ANIMATED } },
    engine      => { required => 0 },
};

my $CHAR = form_compile any => {
    gender      => { required => 0, enum => \%GENDER },
    bloodt      => { required => 0, enum => \%BLOOD_TYPE },
    bust_min    => { required => 0, uint => 1, range => [ 0, 32767 ] },
    bust_max    => { required => 0, uint => 1, range => [ 0, 32767 ] },
    waist_min   => { required => 0, uint => 1, range => [ 0, 32767 ] },
    waist_max   => { required => 0, uint => 1, range => [ 0, 32767 ] },
    hip_min     => { required => 0, uint => 1, range => [ 0, 32767 ] },
    hip_max     => { required => 0, uint => 1, range => [ 0, 32767 ] },
    height_min  => { required => 0, uint => 1, range => [ 0, 32767 ] },
    height_max  => { required => 0, uint => 1, range => [ 0, 32767 ] },
    weight_min  => { required => 0, uint => 1, range => [ 0, 32767 ] },
    weight_max  => { required => 0, uint => 1, range => [ 0, 32767 ] },
    cup_min     => { required => 0, enum => \%CUP_SIZE },
    cup_max     => { required => 0, enum => \%CUP_SIZE },
    va_inc      => { undefarray => { id => 1 } },
    va_exc      => { undefarray => { id => 1 } },
    trait_inc   => { undefarray => { id => 1 } },
    trait_exc   => { undefarray => { id => 1 } },
    tagspoil    => { required => 0, default => 0, uint => 1, range => [0,2] },
    role        => { required => 0, enum => \%CHAR_ROLE },
};

my $STAFF = form_compile any => {
    gender      => { required => 0, enum => [qw[unknown m f]] },
    role        => { undefarray => { enum => [ 'seiyuu', keys %CREDIT_TYPE ] } },
    truename    => { undefbool => 1 },
    lang        => { undefarray => { enum => \%LANGUAGE } },
};


sub debug_validate {
    my($type, $data) = @_;
    my $s = {vn => $VN, release => $RELEASE, char => $CHAR, staff => $STAFF}->{$type};
    my $v = $s->validate($data);
    if(!$v) {
        warn sprintf "Filter validation failed!\nData: %s\nError: %s", JSON::XS->new->canonical->pretty->encode($data), JSON::XS->new->canonical->pretty->encode($v->err);
    } else {
        #warn sprintf "Filter validated: %sSerialized: %s", JSON::XS->new->canonical->pretty->encode($v->data), VNDB::Func::fil_serialize($v->data);
    }
}


# Compatibility with old VN filters. Modifies the filter in-place and returns the number of changes made.
sub filter_vn_compat {
    my($fil) = @_; #XXX: This function is called from old VNDB:: code and the filter data may not have been normalized as per the schema.
    my $mod = 0;

    # older tag specification (by name rather than ID)
    for ('taginc', 'tagexc') {
        my $l = delete $fil->{$_};
        next if !$l;
        $l = [ map lc($_), ref $l ? @$l : $l ];
        $fil->{ s/^tag/tag_/rg } ||= [ map $_->{id}, tuwf->dbAlli(
           'SELECT DISTINCT id FROM tags LEFT JOIN tags_aliases ON id = tag WHERE searchable AND lower(name) IN', $l, 'OR lower(alias) IN', $l
        )->@* ];
        $mod++;
    }

    $mod;
}

1;