Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support regex matching against specific keys #486

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

JeanMertz
Copy link

@JeanMertz JeanMertz commented Jun 17, 2024

edit: See latest comment for the updated design.

I made a small change to the server, to support regex-matching against specific labels in the event.

For example, on macOS, Messages.app's window title consists only of the name of the contact. Matching against "John Doe" with the default regex rule would match either the app or title label, which would be insufficient, as it would also match other apps for which the title contains "John Doe".

With this new KeyValue rule, you can now specifically define in which field the value is expected to match.

For the above example, the following change is made to the configuration JSON:

[
  {
    "id":1,
    "name":["Comms","IM"],
    "rule":{
-      "type":"regex",
+      "type":"keyvalue",
-      "regex":"John Doe"
+      "rules":{"app":{"type":"regex","regex":"Messages"},"title":{"type":"regex","regex":"John Doe"}}
    }
  }
]

Specifically, rule.type is changed from regex to keyvalue and rule.regex is changed to rule.rules which is a list of objects, for which the key is the name of the field you want to match against, and the value is a rule object (so in the future, this could support glob rules as well).

Note that I'm adding these rules directly in the SQLite database, I did not update the UI, so that'll have to be tackled by someone else if this is deemed worthy of including in a future release.

There are also no tests, currently. I'm willing to add those, but it might take a few days/weeks before I get to that. This was mainly a quick change to scratch an itch I had, and I wanted to push this up to see if this can land in an official release in the future.

@JeanMertz
Copy link
Author

After adding some more complex rules, I've determined that my mental model of the relationships between categories and rules was off.

I assumed that a single category could have zero or more rules attached, but in fact it can only have zero or one.

This means that my key/value-based rule is too limiting for more complex set-ups. For example, if I have a category "Chat", and I want for it to include the Messages app with the window title John Doe, but I also want it to have the Discord app without any further specification of the title, then that's currently not possible.

With the current architecture (one rule per category), you'd want to have a higher-level rule that "groups" other rules together. For example, you would have an And rule and an Or rule, those rules would have one or more nested rules of any rule type.

That way, you could express my above example as:

- Chat (category)
	- Or (group rule)
		- KeyValue [app=messages,title=john doe]
		- KeyValue [app=discord]

In this case, the single Or rule would be added to the category, and the rule itself would have data which nests one or more additional rules, of which at least one has to match for the event to be categorized accordingly.

For the server, I don't see any hurdles to implementing this, it's fairly straightforward and mostly the same as what I did with KeyValueRule (since that one also contains nested rules). For the UI, things become more complex, as you need to support a tree of rules, dynamically adding/removing rules from different levels of the tree, supporting drag-and-drop to rearrange grouped rules, etc. Not impossible, but a bit more involved.

I'll probably add the Or and And rules in this PR, as I do have a need for those, but again only for the server, not the UI.

@JeanMertz
Copy link
Author

Alright, I've pushed a change in e830395 (#486) which adds a new "logical rule", which allows infinite nesting of and/or groups of rules to apply more complex matching logic to the events.

Here is one example of my current set-up:

[
  {
    "id": 23,
    "name": [
      "Productivity"
    ],
    "rule": {
      "type": "or",
      "rules": [
        {
          "type": "keyvalue",
          "rules": {
            "app": {
              "type": "regex",
              "regex": "^Shortcuts|Fantastical Helper$"
            }
          }
        },
        {
          "type": "keyvalue",
          "rules": {
            "title": {
              "type": "regex",
              "regex": "^Fantastical$"
            }
          }
        }
      ]
    }
  }
]

Signed-off-by: Jean Mertz <[email protected]>
@JeanMertz
Copy link
Author

I realized that a small (backward-compatible) tweak to the regex rule could negate the need for the keyvalue rule, now that we have the logical or and and rules.

With the latest change, there is now an optional field field on the regex rule, which limits the matching against that single field instead of all fields. Combined with and, you can still get the old keyvalue behaviour, e.g.:

[
  {
    "id": 22,
    "name": [
      "Video"
    ],
    "rule": {
      "type": "and",
      "rules": [
        {
          "type": "regex",
          "field": "app",
          "regex": "^Safari$"
        },
        {
          "type": "regex",
          "field": "title",
          "regex": "YouTube$"
        }
      ]
    }
  },
  {
    "id": 23,
    "name": [
      "Productivity"
    ],
    "rule": {
      "type": "or",
      "rules": [
        {
          "type": "regex",
          "field": "app",
          "regex": "^Shortcuts|Fantastical Helper$"
        },
        {
          "type": "regex",
          "field": "title",
          "regex": "^Fantastical$"
        }
      ]
    }
  }
]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant