raidgrep filtering language
raidgrep
is a bit of a misnomer, as the program should probably be called evtcfind
instead, as it works more akin to find
rather than grep
: While the basic idea was to find logs by a player name, other useful predicates have since emerged (such as #4 (closed), #3 (closed), #2 (closed) and filtering by date). The switch -f
/--fields
has also been added so that we can select whether we want to match the account name or the player name (or both). Yet, handling the flags can become cumbersome and doesn't provide the full power (as they are always conjunctive, i.e. all predicates must be fulfilled).
find
is in a similar position where they support a lot of predicates (such as -name
, -atime
, -empty
), and their "solution" is separate expression language which supports -and
, -or
, grouping by parenthesis, ...
raidgrep
could be updated to allow for a similar language. Something like raidgrep --bosses=dhuum,desmina "Emma Hydes"
could become something like raidgrep -bosses dhuum,desmina -player "Emma Hydes"
, or more specifically even raidgrep (-boss dhuum -or -boss desmina) -and -player "Emma Hydes"
. Just like find
, we would provide some useful shortcuts, e.g. predicates are implicitly joined by -and
if not otherwise given, or shorthands like -bosses
which take a comma-separated list instead of requiring manual -or
s.
The shorthand of raidgrep [NAME]
could still exist for the common case of finding a log by player/account name.
In a similar vein though, even that expression language would maybe not be enough, as some predicates (such as name or profession matching) apply to a single player instead of the whole log. The current behavior is that one of the players must match for the whole log to be included, but we could also provide something like quantified boolean expressions, with a syntax like exists(player p: p.name == "Emma Hydes")
. This would open up a lot of possibilities, for example:
- Find all logs with a Chronomancer called "Godric .*":
exists(player p: p.name ~ "Godric .*" and p.profession == Chronomancer)
. - Find all logs where only scourges are in:
all(player p: p.profession == Scourge)
. - Find all logs where someone called Romeo and someone called Juliet are in:
exists(player p: p.name == "Romeo") and exists(player p: p.name == "Juliet")
.
One thing that we would need to take care of though is the current "early filters", which can filter out logs just by the header, before we have to parse every single event. We could use something like a three-valued logic (similar to SQL's NULL
), and only do the full parsing if the state is "Inconclusive" or "True".
A different question would be the compatibility with the proposed "oneline" output format (see #5), as we'd need to know which player is in the match.