2018-03-21 22:29:58 +01:00
|
|
|
// gomuks - A terminal Matrix client written in Go.
|
|
|
|
// Copyright (C) 2018 Tulir Asokan
|
|
|
|
//
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
package pushrules
|
|
|
|
|
|
|
|
import (
|
2018-05-17 15:29:15 +02:00
|
|
|
"encoding/gob"
|
2018-11-13 23:00:35 +01:00
|
|
|
"maunium.net/go/mautrix"
|
2018-05-22 16:24:47 +02:00
|
|
|
"maunium.net/go/gomuks/lib/glob"
|
2018-03-21 22:29:58 +01:00
|
|
|
)
|
|
|
|
|
2018-05-17 15:29:15 +02:00
|
|
|
func init() {
|
|
|
|
gob.Register(PushRuleArray{})
|
|
|
|
gob.Register(PushRuleMap{})
|
|
|
|
}
|
|
|
|
|
2018-03-23 00:00:13 +01:00
|
|
|
type PushRuleCollection interface {
|
2018-11-13 23:00:35 +01:00
|
|
|
GetActions(room Room, event *mautrix.Event) PushActionArray
|
2018-03-23 00:00:13 +01:00
|
|
|
}
|
|
|
|
|
2018-03-21 22:29:58 +01:00
|
|
|
type PushRuleArray []*PushRule
|
|
|
|
|
2018-05-02 22:05:37 +02:00
|
|
|
func (rules PushRuleArray) SetType(typ PushRuleType) PushRuleArray {
|
2018-03-21 22:29:58 +01:00
|
|
|
for _, rule := range rules {
|
|
|
|
rule.Type = typ
|
|
|
|
}
|
|
|
|
return rules
|
|
|
|
}
|
|
|
|
|
2018-11-13 23:00:35 +01:00
|
|
|
func (rules PushRuleArray) GetActions(room Room, event *mautrix.Event) PushActionArray {
|
2018-03-21 22:29:58 +01:00
|
|
|
for _, rule := range rules {
|
|
|
|
if !rule.Match(room, event) {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
return rule.Actions
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
type PushRuleMap struct {
|
|
|
|
Map map[string]*PushRule
|
|
|
|
Type PushRuleType
|
|
|
|
}
|
|
|
|
|
2018-05-02 22:05:37 +02:00
|
|
|
func (rules PushRuleArray) SetTypeAndMap(typ PushRuleType) PushRuleMap {
|
2018-03-21 22:29:58 +01:00
|
|
|
data := PushRuleMap{
|
|
|
|
Map: make(map[string]*PushRule),
|
|
|
|
Type: typ,
|
|
|
|
}
|
|
|
|
for _, rule := range rules {
|
|
|
|
rule.Type = typ
|
|
|
|
data.Map[rule.RuleID] = rule
|
|
|
|
}
|
|
|
|
return data
|
|
|
|
}
|
|
|
|
|
2018-11-13 23:00:35 +01:00
|
|
|
func (ruleMap PushRuleMap) GetActions(room Room, event *mautrix.Event) PushActionArray {
|
2018-03-21 22:29:58 +01:00
|
|
|
var rule *PushRule
|
|
|
|
var found bool
|
|
|
|
switch ruleMap.Type {
|
|
|
|
case RoomRule:
|
|
|
|
rule, found = ruleMap.Map[event.RoomID]
|
|
|
|
case SenderRule:
|
|
|
|
rule, found = ruleMap.Map[event.Sender]
|
|
|
|
}
|
|
|
|
if found && rule.Match(room, event) {
|
|
|
|
return rule.Actions
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2018-05-02 22:05:37 +02:00
|
|
|
func (ruleMap PushRuleMap) Unmap() PushRuleArray {
|
2018-03-21 22:29:58 +01:00
|
|
|
array := make(PushRuleArray, len(ruleMap.Map))
|
|
|
|
index := 0
|
|
|
|
for _, rule := range ruleMap.Map {
|
|
|
|
array[index] = rule
|
|
|
|
index++
|
|
|
|
}
|
|
|
|
return array
|
|
|
|
}
|
|
|
|
|
|
|
|
type PushRuleType string
|
|
|
|
|
|
|
|
const (
|
|
|
|
OverrideRule PushRuleType = "override"
|
|
|
|
ContentRule PushRuleType = "content"
|
|
|
|
RoomRule PushRuleType = "room"
|
|
|
|
SenderRule PushRuleType = "sender"
|
|
|
|
UnderrideRule PushRuleType = "underride"
|
|
|
|
)
|
|
|
|
|
|
|
|
type PushRule struct {
|
|
|
|
// The type of this rule.
|
|
|
|
Type PushRuleType `json:"-"`
|
|
|
|
// The ID of this rule.
|
|
|
|
// For room-specific rules and user-specific rules, this is the room or user ID (respectively)
|
|
|
|
// For other types of rules, this doesn't affect anything.
|
|
|
|
RuleID string `json:"rule_id"`
|
|
|
|
// The actions this rule should trigger when matched.
|
|
|
|
Actions PushActionArray `json:"actions"`
|
|
|
|
// Whether this is a default rule, or has been set explicitly.
|
|
|
|
Default bool `json:"default"`
|
|
|
|
// Whether or not this push rule is enabled.
|
|
|
|
Enabled bool `json:"enabled"`
|
|
|
|
// The conditions to match in order to trigger this rule.
|
|
|
|
// Only applicable to generic underride/override rules.
|
|
|
|
Conditions []*PushCondition `json:"conditions,omitempty"`
|
|
|
|
// Pattern for content-specific push rules
|
|
|
|
Pattern string `json:"pattern,omitempty"`
|
|
|
|
}
|
|
|
|
|
2018-11-13 23:00:35 +01:00
|
|
|
func (rule *PushRule) Match(room Room, event *mautrix.Event) bool {
|
2018-03-21 22:29:58 +01:00
|
|
|
if !rule.Enabled {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
switch rule.Type {
|
|
|
|
case OverrideRule, UnderrideRule:
|
|
|
|
return rule.matchConditions(room, event)
|
|
|
|
case ContentRule:
|
|
|
|
return rule.matchPattern(room, event)
|
|
|
|
case RoomRule:
|
|
|
|
return rule.RuleID == event.RoomID
|
|
|
|
case SenderRule:
|
|
|
|
return rule.RuleID == event.Sender
|
|
|
|
default:
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-13 23:00:35 +01:00
|
|
|
func (rule *PushRule) matchConditions(room Room, event *mautrix.Event) bool {
|
2018-03-21 22:29:58 +01:00
|
|
|
for _, cond := range rule.Conditions {
|
|
|
|
if !cond.Match(room, event) {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2018-11-13 23:00:35 +01:00
|
|
|
func (rule *PushRule) matchPattern(room Room, event *mautrix.Event) bool {
|
2018-03-21 22:29:58 +01:00
|
|
|
pattern, err := glob.Compile(rule.Pattern)
|
|
|
|
if err != nil {
|
|
|
|
return false
|
|
|
|
}
|
2018-09-05 09:55:48 +02:00
|
|
|
return pattern.MatchString(event.Content.Body)
|
2018-03-21 22:29:58 +01:00
|
|
|
}
|