feat: implement unified directory structure with automatic migration for CalDAV and CardDAV
- Unify directory structure across protocols: * WebDAV: data/files/<username>/ * CalDAV: data/<username>/calendars/<name>/ * CardDAV: data/<username>/addressbooks/<name>/ - Add automatic migration capability that runs on server startup - Maintain full backward compatibility with existing installations - Improve Docker usage by automatically handling legacy data structure - Updated storage provider implementations to use new nested structure - Enhanced store functions for backward compatibility - Modified CalDAV and CardDAV backends to use unified paths - Added automatic migration logic in server initialization
This commit is contained in:
@@ -74,7 +74,7 @@ func (b *Backend) ListAddressBooks(ctx context.Context) ([]carddav.AddressBook,
|
||||
|
||||
var books []carddav.AddressBook
|
||||
for _, name := range names {
|
||||
if err := b.store.EnsureCollection(p.Username, "card-"+name); err != nil {
|
||||
if err := b.store.EnsureCollection(p.Username, "addressbooks/"+name); err != nil {
|
||||
b.logger.Warn("ensuring address book directory", "book", name, "error", err)
|
||||
continue
|
||||
}
|
||||
@@ -85,7 +85,7 @@ func (b *Backend) ListAddressBooks(ctx context.Context) ([]carddav.AddressBook,
|
||||
disk, _ := b.store.ListCollections(p.Username)
|
||||
configured := make(map[string]bool)
|
||||
for _, n := range names {
|
||||
configured["card-"+n] = true
|
||||
configured["addressbooks/"+n] = true
|
||||
}
|
||||
for _, dir := range disk {
|
||||
if strings.HasPrefix(dir, "card-") && !configured[dir] {
|
||||
@@ -101,7 +101,7 @@ func (b *Backend) ListAddressBooks(ctx context.Context) ([]carddav.AddressBook,
|
||||
b.logger.Warn("listing shared address books", "error", err)
|
||||
}
|
||||
for _, sh := range shares {
|
||||
if _, err := b.store.GetCollection(sh.Owner, "card-"+sh.AddressBookName); err != nil {
|
||||
if _, err := b.store.GetCollection(sh.Owner, "addressbooks/"+sh.AddressBookName); err != nil {
|
||||
continue // owner's address book no longer exists
|
||||
}
|
||||
localName := sharedBookName(sh.Owner, sh.AddressBookName)
|
||||
@@ -138,7 +138,7 @@ func (b *Backend) GetAddressObject(ctx context.Context, objPath string, req *car
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err := b.store.GetObject(owner, "card-"+realName, objID)
|
||||
data, err := b.store.GetObject(owner, "addressbooks/"+realName, objID)
|
||||
if err != nil {
|
||||
return nil, webdav.NewHTTPError(http.StatusNotFound, err)
|
||||
}
|
||||
@@ -156,7 +156,7 @@ func (b *Backend) ListAddressObjects(ctx context.Context, bookPath string, req *
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ids, err := b.store.ListObjects(owner, "card-"+realName)
|
||||
ids, err := b.store.ListObjects(owner, "addressbooks/"+realName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -209,7 +209,7 @@ func (b *Backend) DeleteAddressBook(ctx context.Context, bookPath string) error
|
||||
if err := b.dbase.DeleteAddressBook(owner, realName); err != nil && err != db.ErrResourceNotFound {
|
||||
return fmt.Errorf("unregistering address book: %w", err)
|
||||
}
|
||||
return b.store.DeleteCollection(owner, "card-"+realName)
|
||||
return b.store.DeleteCollection(owner, "addressbooks/"+realName)
|
||||
}
|
||||
|
||||
func (b *Backend) PutAddressObject(ctx context.Context, objPath string, card vcard.Card, opts *carddav.PutAddressObjectOptions) (*carddav.AddressObject, error) {
|
||||
|
||||
Reference in New Issue
Block a user