Add parsing users in text

This commit is contained in:
kolaente 2021-07-29 13:34:05 +02:00
parent 6ccb85a0dc
commit 4c5b95cf26
Signed by: konrad
GPG Key ID: F40E70337AB24C9B
3 changed files with 147 additions and 0 deletions

39
pkg/models/mentions.go Normal file
View File

@ -0,0 +1,39 @@
// Vikunja is a to-do list application to facilitate your life.
// Copyright 2018-2021 Vikunja and contributors. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public Licensee 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 Affero General Public Licensee for more details.
//
// You should have received a copy of the GNU Affero General Public Licensee
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package models
import (
"code.vikunja.io/api/pkg/user"
"regexp"
"strings"
"xorm.io/xorm"
)
func FindMentionedUsersInText(s *xorm.Session, text string) (users []*user.User, err error) {
reg := regexp.MustCompile(`@\w+`)
matches := reg.FindAllString(text, -1)
if matches == nil {
return
}
usernames := []string{}
for _, match := range matches {
usernames = append(usernames, strings.TrimPrefix(match, "@"))
}
return user.GetUsersByUsername(s, usernames, true)
}

View File

@ -0,0 +1,87 @@
// Vikunja is a to-do list application to facilitate your life.
// Copyright 2018-2021 Vikunja and contributors. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public Licensee 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 Affero General Public Licensee for more details.
//
// You should have received a copy of the GNU Affero General Public Licensee
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package models
import (
"code.vikunja.io/api/pkg/db"
"code.vikunja.io/api/pkg/user"
"testing"
)
func TestFindMentionedUsersInText(t *testing.T) {
user1 := &user.User{
ID: 1,
}
user2 := &user.User{
ID: 2,
}
tests := []struct {
name string
text string
wantUsers []*user.User
wantErr bool
}{
{
name: "no users mentioned",
text: "Lorem Ipsum dolor sit amet",
},
{
name: "one user at the beginning",
text: "@user1 Lorem Ipsum",
wantUsers: []*user.User{user1},
},
{
name: "one user at the end",
text: "Lorem Ipsum @user1",
wantUsers: []*user.User{user1},
},
{
name: "one user in the middle",
text: "Lorem @user1 Ipsum",
wantUsers: []*user.User{user1},
},
{
name: "same user multiple times",
text: "Lorem @user1 Ipsum @user1 @user1",
wantUsers: []*user.User{user1},
},
{
name: "Multiple users",
text: "Lorem @user1 Ipsum @user2",
wantUsers: []*user.User{user1, user2},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
db.LoadAndAssertFixtures(t)
s := db.NewSession()
defer s.Close()
gotUsers, err := FindMentionedUsersInText(s, tt.text)
if (err != nil) != tt.wantErr {
t.Errorf("FindMentionedUsersInText() error = %v, wantErr %v", err, tt.wantErr)
return
}
for i, u := range gotUsers {
if u.ID != tt.wantUsers[i].ID {
t.Errorf("wanted user %d, got %d at position %d", tt.wantUsers[i].ID, u.ID, i)
}
}
})
}
}

View File

@ -197,6 +197,27 @@ func GetUserByUsername(s *xorm.Session, username string) (user *User, err error)
return getUser(s, &User{Username: username}, false)
}
// GetUsersByUsername returns a slice of users with the provided usernames
func GetUsersByUsername(s *xorm.Session, usernames []string, withEmails bool) (users []*User, err error) {
if len(usernames) == 0 {
return
}
users = []*User{}
err = s.In("username", usernames).Find(&users)
if err != nil {
return
}
if !withEmails {
for _, u := range users {
u.Email = ""
}
}
return
}
// GetUserWithEmail returns a user object with email
func GetUserWithEmail(s *xorm.Session, user *User) (userOut *User, err error) {
return getUser(s, user, true)