Merge pull request #10 from psyko-gh/feature-voice-cast
Added voice option in cast predicate + Docs lint
This commit is contained in:
2
.github/workflows/contribution.yaml
vendored
2
.github/workflows/contribution.yaml
vendored
@@ -24,6 +24,8 @@ jobs:
|
||||
run: npm run lint
|
||||
- name: Format
|
||||
run: npm run format
|
||||
- name: Docs format
|
||||
run: npm run format-docs
|
||||
- name: Build
|
||||
run: npm run build
|
||||
- name: Tests
|
||||
|
||||
@@ -67,21 +67,23 @@ config:
|
||||
- name: Accept favorites actors
|
||||
whenMatch:
|
||||
- cast:
|
||||
- Jenna Ortega
|
||||
- Michael Keaton
|
||||
- Denzel Washington
|
||||
- Keanu Reeves
|
||||
- Jessica Alba
|
||||
- Halle Berry
|
||||
- Sydney Sweeney
|
||||
- Tom Hanks
|
||||
- Samuel L. Jackson
|
||||
- Morgan Freeman
|
||||
- Anthony Hopkins
|
||||
- Gal Gadot
|
||||
- Tom Cruise
|
||||
- Brad Pitt
|
||||
- Matt Damon
|
||||
voice: exclude
|
||||
names:
|
||||
- Jenna Ortega
|
||||
- Michael Keaton
|
||||
- Denzel Washington
|
||||
- Keanu Reeves
|
||||
- Jessica Alba
|
||||
- Halle Berry
|
||||
- Sydney Sweeney
|
||||
- Tom Hanks
|
||||
- Samuel L. Jackson
|
||||
- Morgan Freeman
|
||||
- Anthony Hopkins
|
||||
- Gal Gadot
|
||||
- Tom Cruise
|
||||
- Brad Pitt
|
||||
- Matt Damon
|
||||
action: accept
|
||||
- name: Reject declining actors
|
||||
whenMatch:
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
# Schema
|
||||
|
||||
The JSON Schema is available here: https://github.com/psyko-gh/overcrawlrr/blob/master/schema/schema.json
|
||||
|
||||
@@ -9,25 +9,27 @@ Overcrawlrr configuration is defined in the `settings.yaml` searched by default
|
||||
---
|
||||
|
||||
### Overseerr authentication
|
||||
|
||||
Overcrawlrr need to authenticate to Overseerr to fetch movie information and create movie requests.
|
||||
|
||||
It is recommended to create a [local user in Overseerr](https://docs.overseerr.dev/using-overseerr/users#creating-local-users) dedicated to Overcrawlrr.
|
||||
Doing so, you can have fine-grained control on its permissions:
|
||||
|
||||
- Allow/deny automatic requests validation,
|
||||
- Allow/deny to request in 4K,
|
||||
- Specify the languages and the region when discovering movies,
|
||||
- And more...
|
||||
- Allow/deny automatic requests validation,
|
||||
- Allow/deny to request in 4K,
|
||||
- Specify the languages and the region when discovering movies,
|
||||
- And more...
|
||||
|
||||
Once the user is created, you can fill these value in Overcrawlrr `settings.yaml`:
|
||||
|
||||
```yaml title="settings.yaml"
|
||||
config:
|
||||
config:
|
||||
overseerr:
|
||||
apiUrl: xxx # required
|
||||
user: xxx # required
|
||||
password: xxx # required
|
||||
dryRun: true # Optional - dryRun will not send requests to Overseerr
|
||||
# allowing you to test your rules
|
||||
apiUrl: xxx # required
|
||||
user: xxx # required
|
||||
password: xxx # required
|
||||
dryRun: true # Optional - dryRun will not send requests to Overseerr
|
||||
# allowing you to test your rules
|
||||
```
|
||||
|
||||
---
|
||||
@@ -39,37 +41,38 @@ Once the user is created, you can fill these value in Overcrawlrr `settings.yaml
|
||||
This authentication is optional and only required if you're using the Smart Recommendations job
|
||||
|
||||
To read data from your Plex library, you have to specify your Plex URL and token in `settings.yaml`:
|
||||
|
||||
```yaml title="settings.yaml"
|
||||
config:
|
||||
config:
|
||||
# Only required when using Smart recommendations job
|
||||
plex:
|
||||
apiUrl: xxx
|
||||
plexToken: xxx
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
### Using environment variables
|
||||
|
||||
You can refer to environment variables using the `{{ key }}` syntax.
|
||||
|
||||
```yaml title="settings.yaml"
|
||||
config:
|
||||
config:
|
||||
overseerr:
|
||||
apiUrl: xxx
|
||||
user: '{{ OVERSEERR_USER }}'
|
||||
password: '{{ OVERSEERR_PASSWORD }}'
|
||||
apiUrl: xxx
|
||||
user: '{{ OVERSEERR_USER }}'
|
||||
password: '{{ OVERSEERR_PASSWORD }}'
|
||||
```
|
||||
|
||||
These variables can be defined in the `docker-compose.yaml`
|
||||
|
||||
```yaml title="docker-compose.yaml"
|
||||
services:
|
||||
overcrawlrr:
|
||||
# ...
|
||||
environment:
|
||||
- OVERSEERR_USER=
|
||||
- OVERSEERR_PASSWORD=
|
||||
overcrawlrr:
|
||||
# ...
|
||||
environment:
|
||||
- OVERSEERR_USER=
|
||||
- OVERSEERR_PASSWORD=
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -4,23 +4,21 @@
|
||||
|
||||
Using Overcrawlrr requires you to have a running instance of Overseerr
|
||||
|
||||
|
||||
With docker-compose
|
||||
|
||||
```yaml
|
||||
services:
|
||||
overcrawlrr:
|
||||
image: ghcr.io/psyko-gh/overcrawlrr:latest
|
||||
container_name: overcrawlrr
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- 5056:5056
|
||||
environment:
|
||||
- OVERSEERR_USER=
|
||||
- OVERSEERR_PASSWORD=
|
||||
volumes:
|
||||
- /path/to/config:/config
|
||||
|
||||
overcrawlrr:
|
||||
image: ghcr.io/psyko-gh/overcrawlrr:latest
|
||||
container_name: overcrawlrr
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- 5056:5056
|
||||
environment:
|
||||
- OVERSEERR_USER=
|
||||
- OVERSEERR_PASSWORD=
|
||||
volumes:
|
||||
- /path/to/config:/config
|
||||
```
|
||||
|
||||
With docker cli
|
||||
|
||||
67
docs/jobs.md
67
docs/jobs.md
@@ -10,19 +10,19 @@ It will fetch movies from Overseerr _(from the upcoming/popular/trending section
|
||||
|
||||
```yaml title="settings.yaml"
|
||||
config:
|
||||
overseer:
|
||||
# ....
|
||||
discovery:
|
||||
# Required
|
||||
cron: '30 3 * * *'
|
||||
# Required - the overseer streams to search through
|
||||
# Possible values: upcoming, popular, trending
|
||||
streams:
|
||||
- upcoming
|
||||
- popular
|
||||
- trending
|
||||
# Required - the name of the ruleset used to evaluate movies
|
||||
ruleset: Ruleset name
|
||||
overseer:
|
||||
# ....
|
||||
discovery:
|
||||
# Required
|
||||
cron: '30 3 * * *'
|
||||
# Required - the overseer streams to search through
|
||||
# Possible values: upcoming, popular, trending
|
||||
streams:
|
||||
- upcoming
|
||||
- popular
|
||||
- trending
|
||||
# Required - the name of the ruleset used to evaluate movies
|
||||
ruleset: Ruleset name
|
||||
```
|
||||
|
||||
## Smart recommendations
|
||||
@@ -37,19 +37,38 @@ Considering the movie you liked, it will crawl their recommended movies and appl
|
||||
|
||||
```yaml title="settings.yaml"
|
||||
config:
|
||||
plex:
|
||||
# ....
|
||||
smartRecommendations:
|
||||
# Required
|
||||
cron: '1 14 * * *'
|
||||
# The name of the plex library to use as a seed
|
||||
plexLibrary: Films
|
||||
# Your minimum personal rating to consider
|
||||
minimumRating: 6.9
|
||||
ruleset: Ruleset name
|
||||
plex:
|
||||
# ....
|
||||
smartRecommendations:
|
||||
# Required
|
||||
cron: '1 14 * * *'
|
||||
# The name of the plex library to use as a seed
|
||||
plexLibrary: Films
|
||||
# Your minimum personal rating to consider
|
||||
minimumRating: 6.9
|
||||
ruleset: Ruleset name
|
||||
```
|
||||
|
||||
## Checking output
|
||||
## Testing jobs
|
||||
|
||||
### Evaluating a ruleset
|
||||
|
||||
You can also evaluate a ruleset against a specific movie, using the following URL:
|
||||
|
||||
```
|
||||
http://localhost:5056/api/movies/<id_movie>/evaluate/<ruleset_name>
|
||||
```
|
||||
|
||||
Simply replace `<id_movie>` and `<rulest_name>` by the values matching your needs.
|
||||
|
||||
To find the ID of a movie, navigate to the movie in Overseerr. The ID is the number is the URL.
|
||||
|
||||
### Manually triggering jobs
|
||||
|
||||
You can manually trigger the job by accessing the following URL (assuming Overcrawlrr is accessible at `http://localhost:5056`):
|
||||
|
||||
- Discover job: `http://localhost:5056/api/discover`
|
||||
- Smart recommendations job: `http://localhost:5056/api/smartRecommendations`
|
||||
|
||||
Evaluation of the jobs are displayed in the container log. If you named your service `overcrawlrr`, you can see it with the following command:
|
||||
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
Filters on the adult status of the movie.
|
||||
|
||||
```yaml
|
||||
- adult: yes
|
||||
# or
|
||||
- adult: no
|
||||
- adult: yes
|
||||
# or
|
||||
- adult: no
|
||||
```
|
||||
|
||||
---
|
||||
@@ -19,25 +19,27 @@ Filters on the age of the movie.
|
||||
See [Duration expressions](#duration-expressions) for more details
|
||||
|
||||
```yaml
|
||||
- age: less than 2 years
|
||||
# or
|
||||
- age: more than 6 months
|
||||
- age: less than 2 years
|
||||
# or
|
||||
- age: more than 6 months
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `and`
|
||||
|
||||
Predicate that will match if all of its predicate matches
|
||||
|
||||
```yaml
|
||||
# Will match if the movie is less than 2 years old AND if the movie genre is 'animation'
|
||||
- and:
|
||||
- age: less than 2 years
|
||||
- genre:
|
||||
# Will match if the movie is less than 2 years old AND if the movie genre is 'animation'
|
||||
- and:
|
||||
- age: less than 2 years
|
||||
- genre:
|
||||
- animation
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `cast`
|
||||
|
||||
Filters based on the cast of the movie. Will match when one or more of the listed name matches.
|
||||
@@ -45,12 +47,22 @@ Filters based on the cast of the movie. Will match when one or more of the liste
|
||||
**Case insensitive**
|
||||
|
||||
```yaml
|
||||
- cast:
|
||||
- Denzel Washington
|
||||
- Jessica Alba
|
||||
- cast:
|
||||
- Denzel Washington
|
||||
- Jessica Alba
|
||||
```
|
||||
|
||||
It is also possible to exclude an cast when it's performing voice only (in animation movies for example)
|
||||
|
||||
```yaml
|
||||
- cast:
|
||||
voice: exclude
|
||||
names:
|
||||
- Scarlett Johansson
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `crew`
|
||||
|
||||
Filters based on the crew of the movie. Will match when one or more of the listed name matches.
|
||||
@@ -58,21 +70,23 @@ Filters based on the crew of the movie. Will match when one or more of the liste
|
||||
**Case insensitive**
|
||||
|
||||
```yaml
|
||||
- crew:
|
||||
- James Cameron
|
||||
- Hans Zimmer
|
||||
- crew:
|
||||
- James Cameron
|
||||
- Hans Zimmer
|
||||
```
|
||||
|
||||
It is also possible to specify the job
|
||||
|
||||
```yaml
|
||||
- crew:
|
||||
job: director
|
||||
names:
|
||||
- crew:
|
||||
job: director
|
||||
names:
|
||||
- James Cameron
|
||||
- Steven Spielberg
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `genre`
|
||||
|
||||
Filters on the genre of the movie. Will match when one or more of the listed genres matches the genre of the movie.
|
||||
@@ -80,25 +94,27 @@ Filters on the genre of the movie. Will match when one or more of the listed gen
|
||||
**Case insensitive**
|
||||
|
||||
```yaml
|
||||
- genre: musical
|
||||
# or with an array of values
|
||||
- genre:
|
||||
- animation
|
||||
- romance
|
||||
- genre: musical
|
||||
# or with an array of values
|
||||
- genre:
|
||||
- animation
|
||||
- romance
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `not`
|
||||
|
||||
Predicate that invert the result of its child predicate
|
||||
|
||||
```yaml
|
||||
- not:
|
||||
- genre:
|
||||
- not:
|
||||
- genre:
|
||||
- animation
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `originalLanguage`
|
||||
|
||||
Filters on the original language of the movie
|
||||
@@ -106,27 +122,29 @@ Filters on the original language of the movie
|
||||
**Case insensitive**
|
||||
|
||||
```yaml
|
||||
# ISO 639-1 format of the language (de, au, us, fr...)
|
||||
- originalLanguage: en
|
||||
# or with an array of values
|
||||
- originalLanguage:
|
||||
- en
|
||||
- fr
|
||||
# ISO 639-1 format of the language (de, au, us, fr...)
|
||||
- originalLanguage: en
|
||||
# or with an array of values
|
||||
- originalLanguage:
|
||||
- en
|
||||
- fr
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `or`
|
||||
|
||||
Predicate that will match if any of its predicate matches
|
||||
|
||||
```yaml
|
||||
# Will match if the movie is less than 2 years old OR if the movie score is above 8
|
||||
- or:
|
||||
- age: less than 2 years
|
||||
- score: above 8
|
||||
# Will match if the movie is less than 2 years old OR if the movie score is above 8
|
||||
- or:
|
||||
- age: less than 2 years
|
||||
- score: above 8
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `productionCompany`
|
||||
|
||||
Filters based on the production companies of the movie. Will match when one or more of the listed company matches.
|
||||
@@ -134,24 +152,26 @@ Filters based on the production companies of the movie. Will match when one or m
|
||||
**Case insensitive**
|
||||
|
||||
```yaml
|
||||
- productionCompany:
|
||||
- 20th Century Fox
|
||||
- Warner Bros. Pictures
|
||||
- Twisted Pictures
|
||||
- productionCompany:
|
||||
- 20th Century Fox
|
||||
- Warner Bros. Pictures
|
||||
- Twisted Pictures
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `released`
|
||||
|
||||
Filters on the released status of the movie.
|
||||
|
||||
```yaml
|
||||
- released: yes
|
||||
# or
|
||||
- released: no
|
||||
- released: yes
|
||||
# or
|
||||
- released: no
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `runtime`
|
||||
|
||||
Filters on the runtime _(duration)_ of the movie.
|
||||
@@ -159,12 +179,13 @@ Filters on the runtime _(duration)_ of the movie.
|
||||
See [Duration expressions](#duration-expressions) for more details
|
||||
|
||||
```yaml
|
||||
- runtime: less than 2.5 hours
|
||||
# or
|
||||
- runtime: more than 120 minutes
|
||||
- runtime: less than 2.5 hours
|
||||
# or
|
||||
- runtime: more than 120 minutes
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `score`
|
||||
|
||||
Filters on the score of the movie.
|
||||
@@ -172,12 +193,13 @@ Filters on the score of the movie.
|
||||
Overseerr score is expressed between 0 to 10, but to make things clear, it is possible to pass the score as a fractional number.
|
||||
|
||||
```yaml
|
||||
- score: above 6.5
|
||||
# or
|
||||
- score: below 75/100 # Would be the same as 7.5, 7.5/10 or even 750/1000
|
||||
- score: above 6.5
|
||||
# or
|
||||
- score: below 75/100 # Would be the same as 7.5, 7.5/10 or even 750/1000
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `status`
|
||||
|
||||
Filters on the status of the movie.
|
||||
@@ -187,24 +209,24 @@ The possible values are the one provided by [TMDB](https://www.themoviedb.org/):
|
||||
**Case insensitive**
|
||||
|
||||
```yaml
|
||||
- status: released
|
||||
# or with an array of values
|
||||
- status:
|
||||
- released
|
||||
- post production
|
||||
- planned
|
||||
- status: released
|
||||
# or with an array of values
|
||||
- status:
|
||||
- released
|
||||
- post production
|
||||
- planned
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `voteCount`
|
||||
|
||||
Filters on the vote count of the movie.
|
||||
|
||||
|
||||
```yaml
|
||||
- voteCount: above 1000
|
||||
# or
|
||||
- voteCount: below 100
|
||||
- voteCount: above 1000
|
||||
# or
|
||||
- voteCount: below 100
|
||||
```
|
||||
|
||||
---
|
||||
@@ -216,11 +238,11 @@ Filters based on the available Streaming/VOD platforms. Will match when one or m
|
||||
**Case insensitive**
|
||||
|
||||
```yaml
|
||||
# This predicate will match when the movie is available in Germany on Netflix or Amazon Prime
|
||||
- watchProviders:
|
||||
# ISO 3166-1 alpha-2 format of the region (de, au, us, fr...)
|
||||
- region: de
|
||||
- names:
|
||||
# This predicate will match when the movie is available in Germany on Netflix or Amazon Prime
|
||||
- watchProviders:
|
||||
# ISO 3166-1 alpha-2 format of the region (de, au, us, fr...)
|
||||
- region: de
|
||||
- names:
|
||||
- Netflix
|
||||
- Amazon Prime
|
||||
```
|
||||
@@ -231,12 +253,12 @@ Filters based on the available Streaming/VOD platforms. Will match when one or m
|
||||
|
||||
Duration expressions, like the one used in the `age` or `runtime` predicate can be expressed in the following way:
|
||||
|
||||
- an **operator**: `less than` or `more than`
|
||||
- a integer or decimal **number**: `2` or `2.5`
|
||||
- a **unit**: one of the following `year`, `month`, `week`, `day`, `hour`, `minute`. Singular or plural doesn't matter, so `hour` is the same as `hours`
|
||||
- an **operator**: `less than` or `more than`
|
||||
- a integer or decimal **number**: `2` or `2.5`
|
||||
- a **unit**: one of the following `year`, `month`, `week`, `day`, `hour`, `minute`. Singular or plural doesn't matter, so `hour` is the same as `hours`
|
||||
|
||||
The following expressions are valid:
|
||||
|
||||
- `less than 1 hour`/`less than 1 hours`/`less than 60 minutes`
|
||||
- `less than 3 hours`/`less than 3 hour`/`less than 180 minute`
|
||||
- `more than 6 month`
|
||||
- `less than 1 hour`/`less than 1 hours`/`less than 60 minutes`
|
||||
- `less than 3 hours`/`less than 3 hour`/`less than 180 minute`
|
||||
- `more than 6 month`
|
||||
|
||||
111
docs/rulesets.md
111
docs/rulesets.md
@@ -8,24 +8,24 @@ A ruleset is a named group of rules.
|
||||
|
||||
```yaml title="settings.yaml"
|
||||
config:
|
||||
# ...
|
||||
rulesets:
|
||||
# Required - the name of the ruleset
|
||||
- name: Ruleset name
|
||||
# Optional - the name of another ruleset.
|
||||
# This ruleset will apply all the rules in the extended ruleset
|
||||
# before applying its own rules
|
||||
extends: Another ruleset
|
||||
# Required - An array defining the rules of the ruleset
|
||||
rules:
|
||||
- # rule 1
|
||||
- # rule 2
|
||||
- # rule ...
|
||||
# ...
|
||||
rulesets:
|
||||
# Required - the name of the ruleset
|
||||
- name: Ruleset name
|
||||
# Optional - the name of another ruleset.
|
||||
# This ruleset will apply all the rules in the extended ruleset
|
||||
# before applying its own rules
|
||||
extends: Another ruleset
|
||||
# Required - An array defining the rules of the ruleset
|
||||
rules:
|
||||
- # rule 1
|
||||
- # rule 2
|
||||
- # rule ...
|
||||
```
|
||||
|
||||
- The rules are applied in the declared order,
|
||||
- When a rule matches, the rule's `action` is applied, and the evaluation of the ruleset stops.
|
||||
- If a rule doesn't match, it is ignored, and the next rule is evaluated.
|
||||
- The rules are applied in the declared order,
|
||||
- When a rule matches, the rule's `action` is applied, and the evaluation of the ruleset stops.
|
||||
- If a rule doesn't match, it is ignored, and the next rule is evaluated.
|
||||
|
||||
---
|
||||
|
||||
@@ -36,25 +36,25 @@ A rule is a named group of predicates.
|
||||
A predicate is a simple operation allowing to test the property of a movie.
|
||||
|
||||
```yaml title="settings.yaml"
|
||||
# Required - the name of the rule
|
||||
- name: The rule name
|
||||
# Required - an array defining the predicates used in the rule
|
||||
whenMatch:
|
||||
- # predicate 1
|
||||
- # predicate 2
|
||||
- # ...
|
||||
- # predicate n
|
||||
# Required - the action to apply when the rule matches
|
||||
# Possible values: accept or reject
|
||||
action: accept
|
||||
# Required - the name of the rule
|
||||
- name: The rule name
|
||||
# Required - an array defining the predicates used in the rule
|
||||
whenMatch:
|
||||
- # predicate 1
|
||||
- # predicate 2
|
||||
- # ...
|
||||
- # predicate n
|
||||
# Required - the action to apply when the rule matches
|
||||
# Possible values: accept or reject
|
||||
action: accept
|
||||
```
|
||||
|
||||
The rule will match if **all the predicates** in the `whenMatch` match.
|
||||
|
||||
When matching:
|
||||
|
||||
- If `action: accept`, a request is sent to Overseerr to add the movie,
|
||||
- If `action: reject`, the movie is ignored, and the evaluation of the ruleset stops for this movie.
|
||||
- If `action: accept`, a request is sent to Overseerr to add the movie,
|
||||
- If `action: reject`, the movie is ignored, and the evaluation of the ruleset stops for this movie.
|
||||
|
||||
---
|
||||
|
||||
@@ -66,25 +66,26 @@ This is particularly useful for common rejection rules.
|
||||
|
||||
```yaml title="settings.yaml"
|
||||
config:
|
||||
# ...
|
||||
rulesets:
|
||||
- name: exclude-netflix
|
||||
rules:
|
||||
- name: Exclude netflix movies
|
||||
watchProviders:
|
||||
- region: us
|
||||
- names:
|
||||
- Netflix
|
||||
action: reject
|
||||
- name: filter-movies
|
||||
extends: exclude-netflix # movie will be evaluated against exclude-netflix rules first
|
||||
rules:
|
||||
- name: High score
|
||||
whenMatch:
|
||||
- age: less than 1 year
|
||||
- score: above 9/10
|
||||
action: accept
|
||||
# ...
|
||||
rulesets:
|
||||
- name: exclude-netflix
|
||||
rules:
|
||||
- name: Exclude netflix movies
|
||||
watchProviders:
|
||||
- region: us
|
||||
- names:
|
||||
- Netflix
|
||||
action: reject
|
||||
- name: filter-movies
|
||||
extends: exclude-netflix # movie will be evaluated against exclude-netflix rules first
|
||||
rules:
|
||||
- name: High score
|
||||
whenMatch:
|
||||
- age: less than 1 year
|
||||
- score: above 9/10
|
||||
action: accept
|
||||
```
|
||||
|
||||
## Ruleset example
|
||||
|
||||
The following ruleset will:
|
||||
@@ -93,18 +94,18 @@ The following ruleset will:
|
||||
2. Request all movies _(that went through rule 1)_ released in the past year, with a score above 7
|
||||
|
||||
```yaml title="settings.yaml"
|
||||
rulesets:
|
||||
- name: New great movie
|
||||
rules:
|
||||
rulesets:
|
||||
- name: New great movie
|
||||
rules:
|
||||
- name: Reject less wanted genres
|
||||
whenMatch:
|
||||
- genre:
|
||||
- animation
|
||||
- romance
|
||||
- genre:
|
||||
- animation
|
||||
- romance
|
||||
action: reject
|
||||
- name: New great movies
|
||||
whenMatch:
|
||||
- age: less than 1 years
|
||||
- score: above 7
|
||||
- age: less than 1 years
|
||||
- score: above 7
|
||||
action: accept
|
||||
```
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
"lint": "eslint \"./**/*.ts\"",
|
||||
"format:fix": "prettier ./src --write --cache",
|
||||
"format": "prettier ./src --check --cache",
|
||||
"format-docs": "prettier ./docs --check --cache",
|
||||
"format-docs:fix": "prettier ./docs --write --cache",
|
||||
"start": "tsx src/index.ts",
|
||||
"test": "jest"
|
||||
},
|
||||
|
||||
@@ -218,7 +218,18 @@
|
||||
"type": "object",
|
||||
"required": ["cast"],
|
||||
"properties": {
|
||||
"cast": { "type": "array", "items": {"type": "string" }}
|
||||
"cast": {
|
||||
"oneOf": [
|
||||
{ "type": "array", "items": { "type": "string" }},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"voice": { "type": "string", "enum": ["include", "exclude"]},
|
||||
"names": { "type": "array", "items": {"type": "string" }}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -157,6 +157,36 @@ describe('castPredicate', () => {
|
||||
const rule = testRule(new CastPredicate({ cast: ['Jessica Alba'] }));
|
||||
assertRuleDoesntMatch(rule, movie);
|
||||
});
|
||||
|
||||
it('should match with voice field', async () => {
|
||||
const ruleIncludeVoice = testRule(
|
||||
new CastPredicate({
|
||||
cast: {
|
||||
voice: 'include',
|
||||
names: ['Bob Sherman'],
|
||||
},
|
||||
})
|
||||
);
|
||||
const ruleExcludeVoice = testRule(
|
||||
new CastPredicate({
|
||||
cast: {
|
||||
voice: 'exclude',
|
||||
names: ['Bob Sherman'],
|
||||
},
|
||||
})
|
||||
);
|
||||
const ruleExcludeVoice2 = testRule(
|
||||
new CastPredicate({
|
||||
cast: {
|
||||
voice: 'exclude',
|
||||
names: ['Bob Sherman', 'Sigourney Weaver'],
|
||||
},
|
||||
})
|
||||
);
|
||||
assertRuleMatches(ruleIncludeVoice, movie);
|
||||
assertRuleMatches(ruleExcludeVoice2, movie);
|
||||
assertRuleDoesntMatch(ruleExcludeVoice, movie);
|
||||
});
|
||||
});
|
||||
|
||||
describe('crewPredicate', () => {
|
||||
|
||||
@@ -52,7 +52,12 @@ export type AgeOptions = {
|
||||
};
|
||||
|
||||
export type CastOptions = {
|
||||
cast: string[];
|
||||
cast: string[] | CastWithVoiceOptions;
|
||||
};
|
||||
|
||||
export type CastWithVoiceOptions = {
|
||||
voice: 'include' | 'exclude';
|
||||
names: string[];
|
||||
};
|
||||
|
||||
export type GenreOptions = {
|
||||
|
||||
@@ -4,10 +4,13 @@ import { PredicateBuilder } from '@core/lib/rules';
|
||||
import { CastOptions } from '@core/lib/rules/interfaces';
|
||||
|
||||
export class CastPredicate extends TagsPredicate {
|
||||
private excludeVoice: boolean = false;
|
||||
|
||||
constructor(options: CastOptions) {
|
||||
super({
|
||||
terms: options.cast,
|
||||
terms: Array.isArray(options.cast) ? options.cast : options.cast.names,
|
||||
});
|
||||
this.excludeVoice = Array.isArray(options.cast) ? false : options.cast.voice?.toLowerCase() === 'exclude';
|
||||
}
|
||||
|
||||
getTags(movie: MovieDetails): string[] {
|
||||
@@ -16,7 +19,9 @@ export class CastPredicate extends TagsPredicate {
|
||||
}
|
||||
const tags: string[] = [];
|
||||
for (const cast of movie.credits.cast) {
|
||||
tags.push(cast.name);
|
||||
if (!this.excludeVoice || !cast.character || !cast.character.toLowerCase().includes('(voice)')) {
|
||||
tags.push(cast.name);
|
||||
}
|
||||
}
|
||||
return tags;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user