Compare commits

...

10 Commits

Author SHA1 Message Date
Erwan Martin 4f55099896 fix(caldav): do not update dates of tasks when repositioning them
When a task is updated, the position of the tasks of the whole
project/bucket are updated. This leads to column "updated" of
model Task to be updated quite often.
However, that column is used for the ETag field of CALDAV.
Thus, changing a task marks all the other tasks as updated, which
prevents clients from synchronizing their edited tasks.
2023-09-17 17:35:09 +02:00
kolaente f065dcf4ad
fix(typesense): add typesense sync to initial structs 2023-09-15 12:53:29 +02:00
kolaente addcbdd8ca
fix(test): don't check for error 2023-09-13 12:52:42 +02:00
kolaente 054f21821c
fix(typesense): don't try to index tasks if there are none 2023-09-13 12:19:09 +02:00
kolaente 38a3a5c6e8
fix(typesense): explicitely create typesense sync table 2023-09-13 12:05:37 +02:00
kolaente 1ee243f2bd
fix(project background): add more checks for whether a background file exists when duplicating or deleting a project
Related discussion: https://community.vikunja.io/t/500-internal-server-error-when-selecting-unsplash-background-image/778/18
2023-09-13 11:20:59 +02:00
kolaente 191c154150
chore(build): use our own goproxy to prevent issues with packages not found 2023-09-12 13:34:35 +02:00
kolaente 378759e06d
fix(build): don't remove swagger files when running build:clean step 2023-09-12 13:12:30 +02:00
kolaente c5c74e9537
chore(caldav): improve trimming .ics file ending 2023-09-07 15:52:37 +02:00
kolaente e34f503674
fix: lint 2023-09-07 11:31:35 +02:00
14 changed files with 84 additions and 55 deletions

View File

@ -438,6 +438,7 @@ steps:
# This path does not exist. However, when we set the gopath to /go, the build fails. Not sure why.
# Leaving this here until we know how to resolve this properly.
GOPATH: /srv/app
GOPROXY: https://goproxy.kolaente.de
commands:
- export PATH=$PATH:$GOPATH/bin
- go install github.com/magefile/mage
@ -451,6 +452,7 @@ steps:
# This path does not exist. However, when we set the gopath to /go, the build fails. Not sure why.
# Leaving this here until we know how to resolve this properly.
GOPATH: /srv/app
GOPROXY: https://goproxy.kolaente.de
commands:
- export PATH=$PATH:$GOPATH/bin
- go install github.com/magefile/mage
@ -464,6 +466,7 @@ steps:
# This path does not exist. However, when we set the gopath to /go, the build fails. Not sure why.
# Leaving this here until we know how to resolve this properly.
GOPATH: /srv/app
GOPROXY: https://goproxy.kolaente.de
commands:
- export PATH=$PATH:$GOPATH/bin
- go install github.com/magefile/mage
@ -775,6 +778,6 @@ steps:
- failure
---
kind: signature
hmac: b32ea5780ab6c4e57f201ec468357340349591a3026c96efd669a0b9c10f0e34
hmac: 6bc74f5b7e9c51e725100e05f07cdac656d6c3d49d19c2b112aed812c86e7a9a
...

View File

@ -13,6 +13,7 @@ COPY . ./
ARG TARGETOS TARGETARCH TARGETVARIANT
ENV GOPROXY https://goproxy.kolaente.de
RUN export PATH=$PATH:$GOPATH/bin && \
mage build:clean && \
mage release:xgo "${TARGETOS}/${TARGETARCH}/${TARGETVARIANT}"

View File

@ -453,9 +453,6 @@ func (Build) Clean() error {
if err := os.RemoveAll(BinLocation); err != nil && !os.IsNotExist(err) {
return err
}
if err := os.RemoveAll(swaggerDocsFolderLocation); err != nil && !os.IsNotExist(err) {
return err
}
return nil
}

View File

@ -17,13 +17,13 @@
package caldav
import (
"code.vikunja.io/api/pkg/db"
"errors"
"strconv"
"strings"
"time"
"code.vikunja.io/api/pkg/config"
"code.vikunja.io/api/pkg/db"
"code.vikunja.io/api/pkg/log"
"code.vikunja.io/api/pkg/models"
"code.vikunja.io/api/pkg/utils"
@ -91,11 +91,11 @@ func ParseTaskFromVTODO(content string) (vTask *models.Task, err error) {
}
// We put the vTodo details in a map to be able to handle them more easily
task := make(map[string]ics.IANAProperty)
var relation *ics.IANAProperty
var relation ics.IANAProperty
for _, c := range vTodo.UnknownPropertiesIANAProperties() {
task[c.IANAToken] = c
if strings.HasPrefix(c.IANAToken, "RELATED-TO") {
relation = &c
relation = c
}
}
@ -139,7 +139,7 @@ func ParseTaskFromVTODO(content string) (vTask *models.Task, err error) {
DoneAt: caldavTimeToTimestamp(task["COMPLETED"]),
}
if relation != nil {
if relation.Value != "" {
s := db.NewSession()
defer s.Close()

View File

@ -38,7 +38,7 @@ func init() {
ID: "20230828125443",
Description: "",
Migrate: func(tx *xorm.Engine) error {
return tx.Sync2(typesenseSync20230828125443{})
return tx.CreateTables(typesenseSync20230828125443{})
},
Rollback: func(tx *xorm.Engine) error {
return nil

View File

@ -59,6 +59,7 @@ func GetTables() []interface{} {
&Subscription{},
&Favorite{},
&APIToken{},
&TypesenseSync{},
}
}

View File

@ -1030,7 +1030,12 @@ func (p *Project) DeleteBackgroundFileIfExists() (err error) {
}
file := files.File{ID: p.BackgroundFileID}
return file.Delete()
err = file.Delete()
if err != nil && files.IsErrFileDoesNotExist(err) {
return nil
}
return err
}
// SetProjectBackground sets a background file as project background in the db

View File

@ -118,43 +118,9 @@ func (pd *ProjectDuplicate) Create(s *xorm.Session, doer web.Auth) (err error) {
return
}
// Background files + unsplash info
if pd.Project.BackgroundFileID != 0 {
log.Debugf("Duplicating background %d from project %d into %d", pd.Project.BackgroundFileID, pd.ProjectID, pd.Project.ID)
f := &files.File{ID: pd.Project.BackgroundFileID}
if err := f.LoadFileMetaByID(); err != nil {
return err
}
if err := f.LoadFileByID(); err != nil {
return err
}
defer f.File.Close()
file, err := files.Create(f.File, f.Name, f.Size, doer)
if err != nil {
return err
}
// Get unsplash info if applicable
up, err := GetUnsplashPhotoByFileID(s, pd.Project.BackgroundFileID)
if err != nil && files.IsErrFileIsNotUnsplashFile(err) {
return err
}
if up != nil {
up.ID = 0
up.FileID = file.ID
if err := up.Save(s); err != nil {
return err
}
}
if err := SetProjectBackground(s, pd.Project.ID, file, pd.Project.BackgroundBlurHash); err != nil {
return err
}
log.Debugf("Duplicated project background from project %d into %d", pd.ProjectID, pd.Project.ID)
err = duplicateProjectBackground(s, pd, doer)
if err != nil {
return
}
// Rights / Shares
@ -207,6 +173,54 @@ func (pd *ProjectDuplicate) Create(s *xorm.Session, doer web.Auth) (err error) {
return
}
func duplicateProjectBackground(s *xorm.Session, pd *ProjectDuplicate, doer web.Auth) (err error) {
if pd.Project.BackgroundFileID == 0 {
return
}
log.Debugf("Duplicating background %d from project %d into %d", pd.Project.BackgroundFileID, pd.ProjectID, pd.Project.ID)
f := &files.File{ID: pd.Project.BackgroundFileID}
err = f.LoadFileMetaByID()
if err != nil && files.IsErrFileDoesNotExist(err) {
pd.Project.BackgroundFileID = 0
return nil
}
if err != nil {
return err
}
if err := f.LoadFileByID(); err != nil {
return err
}
defer f.File.Close()
file, err := files.Create(f.File, f.Name, f.Size, doer)
if err != nil {
return err
}
// Get unsplash info if applicable
up, err := GetUnsplashPhotoByFileID(s, pd.Project.BackgroundFileID)
if err != nil && !files.IsErrFileIsNotUnsplashFile(err) {
return err
}
if up != nil {
up.ID = 0
up.FileID = file.ID
if err := up.Save(s); err != nil {
return err
}
}
if err := SetProjectBackground(s, pd.Project.ID, file, pd.Project.BackgroundBlurHash); err != nil {
return err
}
log.Debugf("Duplicated project background from project %d into %d", pd.ProjectID, pd.Project.ID)
return
}
func duplicateTasks(s *xorm.Session, doer web.Auth, ld *ProjectDuplicate, bucketMap map[int64]int64) (err error) {
// Get all tasks + all task details
tasks, _, _, err := getTasksForProjects(s, []*Project{{ID: ld.ProjectID}}, doer, &taskSearchOptions{})

View File

@ -329,8 +329,7 @@ func TestProject_DeleteBackgroundFileIfExists(t *testing.T) {
err := SetProjectBackground(s, project.ID, file, "")
assert.NoError(t, err)
err = project.DeleteBackgroundFileIfExists()
assert.Error(t, err)
assert.True(t, files.IsErrFileDoesNotExist(err))
assert.NoError(t, err)
})
t.Run("project without background", func(t *testing.T) {
db.LoadAndAssertFixtures(t)

View File

@ -1083,6 +1083,7 @@ func recalculateTaskKanbanPositions(s *xorm.Session, bucketID int64) (err error)
_, err = s.Cols("kanban_position").
Where("id = ?", task.ID).
NoAutoTime().
Update(&Task{KanbanPosition: currentPosition})
if err != nil {
return
@ -1111,6 +1112,7 @@ func recalculateTaskPositions(s *xorm.Session, projectID int64) (err error) {
_, err = s.Cols("position").
Where("id = ?", task.ID).
NoAutoTime().
Update(&Task{Position: currentPosition})
if err != nil {
return

View File

@ -243,6 +243,12 @@ func ReindexAllTasks() (err error) {
}
func reindexTasks(s *xorm.Session, tasks map[int64]*Task) (err error) {
if len(tasks) == 0 {
log.Infof("No tasks to index")
return
}
err = addMoreInfoToTasks(s, tasks, &user.User{ID: 1})
if err != nil {
return fmt.Errorf("could not fetch more task info: %s", err.Error())

View File

@ -291,11 +291,13 @@ func (p *Provider) Set(s *xorm.Session, image *background.Image, project *models
// Remove the old background if one exists
if project.BackgroundFileID != 0 {
file := files.File{ID: project.BackgroundFileID}
if err := file.Delete(); err != nil {
err = file.Delete()
if err != nil && !files.IsErrFileDoesNotExist(err) {
return err
}
if err := models.RemoveUnsplashPhoto(s, project.BackgroundFileID); err != nil {
err = models.RemoveUnsplashPhoto(s, project.BackgroundFileID)
if err != nil && !files.IsErrFileDoesNotExist(err) {
return err
}
}

View File

@ -56,7 +56,8 @@ func (p *Provider) Set(s *xorm.Session, img *background.Image, project *models.P
// Remove the old background if one exists
if project.BackgroundFileID != 0 {
file := files.File{ID: project.BackgroundFileID}
if err := file.Delete(); err != nil {
err := file.Delete()
if err != nil && !files.IsErrFileDoesNotExist(err) {
return err
}
}

View File

@ -133,9 +133,7 @@ func (vcls *VikunjaCaldavProjectStorage) GetResourcesByList(rpaths []string) ([]
var uids []string
for _, path := range rpaths {
parts := strings.Split(path, "/")
uid := []rune(parts[4]) // The 4th part is the id with ".ics" suffix
endlen := len(uid) - len(".ics") // ".ics" are 4 bytes
uids = append(uids, string(uid[:endlen]))
uids = append(uids, strings.TrimSuffix(parts[4], ".ics"))
}
s := db.NewSession()