The `is` operator must exactly match the field value, while the `includes` operator matches a substring.
The `starts with` operator matches, if the value starts with the given prefix,
and `ends with` matches the opposite. All these matches are case-insensitive.
Valid operands include:
* "string value" (string)
* integer (int)
Valid operands for the enumeration `data_kind` are:
*`file`
*`url`
*`spotify`
*`pipe`
Valid operands for the enumeration `media_kind` are:
*`music`
*`movie`
*`podcast`
*`audiobook`
*`tvshow`
Multiple expressions can be anded or ored together, using the keywords `OR` and `AND`. The unary not operator is also supported using the keyword `NOT`.
It is possible to define the sort order and limit the number of items by adding an order clause and/or a limit clause after the last expression:
```
"Playlist Name" { expression ORDER BY field-name sort-direction LIMIT limit }
```
"sort-direction" is either `ASC` (ascending) or `DESC` (descending). "limit" is the maximum number of items.
There is additionally a special `random`_field-name_ that can be used in conjunction with `limit` to select a random number of items based on current expression.
## Examples
```
"techno" {
genre includes "techno"
and artist includes "zombie"
}
```
This would match songs by "Rob Zombie" or "White Zombie", as well as those with a genre of "Techno-Industrial" or
"Trance/Techno", for example.
```
"techno 2015" {
genre includes "techno"
and artist includes "zombie"
and not genre includes "industrial"
}
```
This would exclude e. g. songs with the genre "Techno-Industrial".
```
"Local music" {
data_kind is file
and media_kind is music
}
```
This would match all songs added as files to the library that are not placed under the folders for podcasts, audiobooks.
```
"Unplayed podcasts and audiobooks" {
play_count = 0
and (media_kind is podcast or media_kind is audiobook)
}
```
This would match any podcast and audiobook file that was never played.
These dates refer to the _start_ of that period; `today` means 00:00hrs of today, `this week` means current Monday 00:00hrs, `last week` means the previous Monday 00:00hrs, `last month` is the first day of the previous month at 00:00hrs etc.
A valid date can also be made by applying an interval to a date. Intervals can be defined as `days`, `weeks`, `months`, `years`.
As an example, a valid date might be:
```3 weeks before today``` or ```3 weeks ago```
Examples:
```
"Recently Added" {
time_added after 2 weeks ago
}
```
This matches all songs added in the last 2 weeks.
```
"Recently played audiobooks" {
time_played after last week
and media_kind is audiobook
}
```
This matches all audiobooks played since the start of the last Monday 00:00AM.
All dates, except for `YYYY-DD-HH`, are relative to the day of when the server evaluates the smartpl query; `time_added after today` run on a Monday would match against items added since Monday 00:00hrs and evaluating the same smartpl on Friday would only match against added on Friday 00:00hrs.
Note that `time_added after 4 weeks ago` and `time_added after last month` are subtly different; the former is exactly 4 weeks ago (from today) whereas the latter is the first day of the previous month.
The syntax is really close to the mt-daapd smart playlist syntax (see [Multi-Threaded DAAP Daemon Code](https://sourceforge.net/p/mt-daapd/code/HEAD/tree/tags/release-0.2.4.2/contrib/mt-daapd.playlist).