mirror of
https://github.com/crawlab-team/crawlab.git
synced 2026-01-21 17:21:09 +01:00
refactor: Update SendNotification function to handle old and new settings triggers
This commit is contained in:
@@ -1,73 +0,0 @@
|
||||
package notification
|
||||
|
||||
import (
|
||||
"github.com/crawlab-team/crawlab/core/interfaces"
|
||||
"github.com/crawlab-team/crawlab/core/models/delegate"
|
||||
"github.com/crawlab-team/crawlab/core/models/models"
|
||||
"github.com/gavv/httpexpect/v2"
|
||||
"github.com/spf13/viper"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func init() {
|
||||
viper.Set("mongo.db", "crawlab_test")
|
||||
var err error
|
||||
T, err = NewTest()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
type Test struct {
|
||||
svc *Service
|
||||
svr *httptest.Server
|
||||
|
||||
// test data
|
||||
TestNode interfaces.Node
|
||||
TestSpider interfaces.Spider
|
||||
TestTask interfaces.Task
|
||||
TestTaskStat interfaces.TaskStat
|
||||
}
|
||||
|
||||
func (t *Test) Setup(t2 *testing.T) {
|
||||
_ = t.svc.Start()
|
||||
t2.Cleanup(t.Cleanup)
|
||||
}
|
||||
|
||||
func (t *Test) Cleanup() {
|
||||
_ = t.svc.Stop()
|
||||
}
|
||||
|
||||
func (t *Test) NewExpect(t2 *testing.T) (e *httpexpect.Expect) {
|
||||
e = httpexpect.New(t2, t.svr.URL)
|
||||
return e
|
||||
}
|
||||
|
||||
var T *Test
|
||||
|
||||
func NewTest() (res *Test, err error) {
|
||||
// test
|
||||
t := &Test{
|
||||
svc: NewService(),
|
||||
}
|
||||
|
||||
// test node
|
||||
t.TestNode = &models.Node{Id: primitive.NewObjectID(), Name: "test-node"}
|
||||
_ = delegate.NewModelDelegate(t.TestNode).Add()
|
||||
|
||||
// test spider
|
||||
t.TestSpider = &models.Spider{Id: primitive.NewObjectID(), Name: "test-spider"}
|
||||
_ = delegate.NewModelDelegate(t.TestSpider).Add()
|
||||
|
||||
// test task
|
||||
t.TestTask = &models.Task{Id: primitive.NewObjectID(), SpiderId: t.TestSpider.GetId(), NodeId: t.TestNode.GetId()}
|
||||
_ = delegate.NewModelDelegate(t.TestTask).Add()
|
||||
|
||||
// test task stat
|
||||
t.TestTaskStat = &models.TaskStat{Id: t.TestTask.GetId()}
|
||||
_ = delegate.NewModelDelegate(t.TestTaskStat).Add()
|
||||
|
||||
return t, nil
|
||||
}
|
||||
@@ -28,7 +28,7 @@ func SendMail(m *models.NotificationSettingMail, to, cc, title, content string)
|
||||
|
||||
// config
|
||||
port, _ := strconv.Atoi(m.Port)
|
||||
password := m.Password // test password: ALWVDPRHBEXOENXD
|
||||
password := m.Password
|
||||
SMTPUser := m.User
|
||||
smtpConfig := smtpAuthentication{
|
||||
Server: m.Server,
|
||||
|
||||
@@ -6,28 +6,19 @@ import (
|
||||
"github.com/crawlab-team/crawlab/core/entity"
|
||||
"github.com/crawlab-team/crawlab/core/models/models/v2"
|
||||
"github.com/crawlab-team/crawlab/core/models/service"
|
||||
mongo2 "github.com/crawlab-team/crawlab/db/mongo"
|
||||
parser "github.com/crawlab-team/crawlab/template-parser"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"regexp"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type ServiceV2 struct {
|
||||
}
|
||||
|
||||
func (svc *ServiceV2) Start() (err error) {
|
||||
func (svc *ServiceV2) Start() {
|
||||
// initialize data
|
||||
if err := svc.initData(); err != nil {
|
||||
return err
|
||||
log.Errorf("[NotificationServiceV2] initializing data error: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (svc *ServiceV2) Stop() (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (svc *ServiceV2) initData() (err error) {
|
||||
@@ -175,187 +166,95 @@ Please find the task data as below.
|
||||
return nil
|
||||
}
|
||||
|
||||
func (svc *ServiceV2) Send(s *models.NotificationSettingV2, entity bson.M) (err error) {
|
||||
func (svc *ServiceV2) Send(s *models.NotificationSettingV2, args ...any) (err error) {
|
||||
content := svc.getContent(s, args...)
|
||||
switch s.Type {
|
||||
case TypeMail:
|
||||
return svc.SendMail(s, entity)
|
||||
return svc.SendMail(s, content)
|
||||
case TypeMobile:
|
||||
return svc.SendMobile(s, entity)
|
||||
return svc.SendMobile(s, content)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (svc *ServiceV2) SendMail(s *models.NotificationSettingV2, entity bson.M) (err error) {
|
||||
// to
|
||||
to, err := parser.Parse(s.Mail.To, entity)
|
||||
if err != nil {
|
||||
log.Warnf("parsing 'to' error: %v", err)
|
||||
}
|
||||
if to == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
// cc
|
||||
cc, err := parser.Parse(s.Mail.Cc, entity)
|
||||
if err != nil {
|
||||
log.Warnf("parsing 'cc' error: %v", err)
|
||||
}
|
||||
|
||||
// title
|
||||
title, err := parser.Parse(s.Title, entity)
|
||||
if err != nil {
|
||||
log.Warnf("parsing 'title' error: %v", err)
|
||||
}
|
||||
|
||||
// content
|
||||
content, err := parser.Parse(s.TemplateMarkdown, entity)
|
||||
if err != nil {
|
||||
log.Warnf("parsing 'content' error: %v", err)
|
||||
}
|
||||
func (svc *ServiceV2) SendMail(s *models.NotificationSettingV2, content string) (err error) {
|
||||
// TODO: parse to/cc/bcc
|
||||
|
||||
// send mail
|
||||
if err := SendMail(&s.Mail, to, cc, title, content); err != nil {
|
||||
if err := SendMail(&s.Mail, s.Mail.To, s.Mail.Cc, s.Title, content); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (svc *ServiceV2) SendMobile(s *models.NotificationSettingV2, entity bson.M) (err error) {
|
||||
// webhook
|
||||
webhook, err := parser.Parse(s.Mobile.Webhook, entity)
|
||||
if err != nil {
|
||||
log.Warnf("parsing 'webhook' error: %v", err)
|
||||
}
|
||||
if webhook == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
// title
|
||||
title, err := parser.Parse(s.Title, entity)
|
||||
if err != nil {
|
||||
log.Warnf("parsing 'title' error: %v", err)
|
||||
}
|
||||
|
||||
// content
|
||||
content, err := parser.Parse(s.TemplateMarkdown, entity)
|
||||
if err != nil {
|
||||
log.Warnf("parsing 'content' error: %v", err)
|
||||
}
|
||||
|
||||
func (svc *ServiceV2) SendMobile(s *models.NotificationSettingV2, content string) (err error) {
|
||||
// send
|
||||
if err := SendMobileNotification(webhook, title, content); err != nil {
|
||||
if err := SendMobileNotification(s.Mobile.Webhook, s.Title, content); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (svc *ServiceV2) GetSettingList(query bson.M, pagination *entity.Pagination, sort bson.D) (res []models.NotificationSettingV2, total int, err error) {
|
||||
// options
|
||||
var options *mongo2.FindOptions
|
||||
if pagination != nil || sort != nil {
|
||||
options = new(mongo2.FindOptions)
|
||||
if pagination != nil {
|
||||
options.Skip = pagination.Size * (pagination.Page - 1)
|
||||
options.Limit = pagination.Size
|
||||
}
|
||||
if sort != nil {
|
||||
options.Sort = sort
|
||||
func (svc *ServiceV2) getContent(s *models.NotificationSettingV2, args ...any) (content string) {
|
||||
switch s.TriggerTarget {
|
||||
case constants.NotificationTriggerTargetTask:
|
||||
//task := new(models.TaskV2)
|
||||
//taskStat := new(models.TaskStatV2)
|
||||
//spider := new(models.SpiderV2)
|
||||
//node := new(models.NodeV2)
|
||||
//for _, arg := range args {
|
||||
// switch arg.(type) {
|
||||
// case models.TaskV2:
|
||||
// task = arg.(*models.TaskV2)
|
||||
// case models.TaskStatV2:
|
||||
// taskStat = arg.(*models.TaskStatV2)
|
||||
// case models.SpiderV2:
|
||||
// spider = arg.(*models.SpiderV2)
|
||||
// case models.NodeV2:
|
||||
// node = arg.(*models.NodeV2)
|
||||
// }
|
||||
//}
|
||||
switch s.TemplateMode {
|
||||
case constants.NotificationTemplateModeMarkdown:
|
||||
// TODO: implement
|
||||
case constants.NotificationTemplateModeRichText:
|
||||
//s.TemplateRichText
|
||||
}
|
||||
|
||||
case constants.NotificationTriggerTargetNode:
|
||||
|
||||
}
|
||||
|
||||
// get list
|
||||
list, err := service.NewModelServiceV2[models.NotificationSettingV2]().GetMany(query, options)
|
||||
if err != nil {
|
||||
if err.Error() == mongo.ErrNoDocuments.Error() {
|
||||
return nil, 0, nil
|
||||
} else {
|
||||
return nil, 0, err
|
||||
}
|
||||
}
|
||||
|
||||
// total count
|
||||
total, err = service.NewModelServiceV2[models.NotificationSettingV2]().Count(query)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
return list, total, nil
|
||||
return content
|
||||
}
|
||||
|
||||
func (svc *ServiceV2) GetSetting(id primitive.ObjectID) (res *models.NotificationSettingV2, err error) {
|
||||
s, err := service.NewModelServiceV2[models.NotificationSettingV2]().GetById(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
func (svc *ServiceV2) parseTemplateVariables(s *models.NotificationSettingV2) (variables []entity.NotificationVariable) {
|
||||
regex := regexp.MustCompile("\\$\\{(\\w+):(\\w+)}")
|
||||
|
||||
func (svc *ServiceV2) PosSetting(s *models.NotificationSettingV2) (err error) {
|
||||
s.Id = primitive.NewObjectID()
|
||||
_, err = service.NewModelServiceV2[models.NotificationSettingV2]().InsertOne(*s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
// find all matches
|
||||
matches := regex.FindAllStringSubmatch(s.Template, -1)
|
||||
|
||||
func (svc *ServiceV2) PutSetting(id primitive.ObjectID, s models.NotificationSettingV2) (err error) {
|
||||
err = service.NewModelServiceV2[models.NotificationSettingV2]().ReplaceById(id, s)
|
||||
if err != nil {
|
||||
return err
|
||||
// iterate over matches
|
||||
for _, match := range matches {
|
||||
variables = append(variables, entity.NotificationVariable{
|
||||
Category: match[1],
|
||||
Name: match[2],
|
||||
})
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (svc *ServiceV2) DeleteSetting(id primitive.ObjectID) (err error) {
|
||||
err = service.NewModelServiceV2[models.NotificationSettingV2]().DeleteById(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (svc *ServiceV2) EnableSetting(id primitive.ObjectID) (err error) {
|
||||
return svc._toggleSettingFunc(true)(id)
|
||||
}
|
||||
|
||||
func (svc *ServiceV2) DisableSetting(id primitive.ObjectID) (err error) {
|
||||
return svc._toggleSettingFunc(false)(id)
|
||||
}
|
||||
|
||||
func (svc *ServiceV2) _toggleSettingFunc(value bool) func(id primitive.ObjectID) error {
|
||||
return func(id primitive.ObjectID) (err error) {
|
||||
s, err := service.NewModelServiceV2[models.NotificationSettingV2]().GetById(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.Enabled = value
|
||||
err = service.NewModelServiceV2[models.NotificationSettingV2]().ReplaceById(id, *s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return variables
|
||||
}
|
||||
|
||||
func newNotificationServiceV2() *ServiceV2 {
|
||||
// service
|
||||
svc := &ServiceV2{}
|
||||
|
||||
return svc
|
||||
return &ServiceV2{}
|
||||
}
|
||||
|
||||
var _serviceV2 *ServiceV2
|
||||
var _serviceV2Once = new(sync.Once)
|
||||
|
||||
func GetNotificationServiceV2() *ServiceV2 {
|
||||
if _serviceV2 != nil {
|
||||
return _serviceV2
|
||||
}
|
||||
_serviceV2Once.Do(func() {
|
||||
_serviceV2 = newNotificationServiceV2()
|
||||
})
|
||||
|
||||
39
core/notification/service_v2_test.go
Normal file
39
core/notification/service_v2_test.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package notification
|
||||
|
||||
import (
|
||||
"github.com/crawlab-team/crawlab/core/entity"
|
||||
"github.com/crawlab-team/crawlab/core/models/models/v2"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestParseTemplateVariables_WithValidTemplate_ReturnsVariables(t *testing.T) {
|
||||
svc := ServiceV2{}
|
||||
template := "Dear ${user:name}, your task ${task:id} is ${task:status}."
|
||||
expected := []entity.NotificationVariable{
|
||||
{Category: "user", Name: "name"},
|
||||
{Category: "task", Name: "id"},
|
||||
{Category: "task", Name: "status"},
|
||||
}
|
||||
setting := models.NotificationSettingV2{Template: template}
|
||||
|
||||
variables := svc.parseTemplateVariables(&setting)
|
||||
|
||||
assert.Equal(t, expected, variables)
|
||||
}
|
||||
|
||||
func TestParseTemplateVariables_WithRepeatedVariables_ReturnsUniqueVariables(t *testing.T) {
|
||||
svc := ServiceV2{}
|
||||
template := "Dear ${user:name}, your task ${task:id} is ${task:status}. Again, ${user:name} and ${task:id}."
|
||||
expected := []entity.NotificationVariable{
|
||||
{Category: "user", Name: "name"},
|
||||
{Category: "task", Name: "id"},
|
||||
{Category: "task", Name: "status"},
|
||||
}
|
||||
setting := models.NotificationSettingV2{Template: template}
|
||||
|
||||
variables := svc.parseTemplateVariables(&setting)
|
||||
|
||||
assert.Equal(t, expected, variables)
|
||||
}
|
||||
Reference in New Issue
Block a user