🎨 Adjust iCalendar files directory structure

This commit is contained in:
颖逸 2024-12-01 03:43:16 +08:00
parent 432bb826f3
commit 72fbc9ca87
No known key found for this signature in database
GPG key ID: 833DAD5428FF18A8
3 changed files with 82 additions and 20 deletions

View file

@ -18,6 +18,7 @@ package model
import (
"context"
"sync"
"github.com/emersion/go-ical"
"github.com/emersion/go-webdav/caldav"
@ -32,7 +33,9 @@ const (
CalDavHomeSetPath = CalDavUserPrincipalPath + "/calendars" // 2 resourceTypeCalendarHomeSet
CalDavDefaultCalendarPath = CalDavHomeSetPath + "/default" // 3 resourceTypeCalendar
ICalendarFileExt = ".ics"
CalDavDefaultCalendarName = "default"
ICalendarFileExt = "." + ical.Extension // .ics
)
type CalDavPathDepth int
@ -46,6 +49,48 @@ const (
calDavPathDepth_Object // /caldav/principals/main/calendars/default/id.ics
)
var (
calendarMaxResourceSize int64 = 0
calendarSupportedComponentSet = []string{"VEVENT", "VTODO"}
defaultCalendar = caldav.Calendar{
Path: CalDavDefaultCalendarPath,
Name: CalDavDefaultCalendarName,
Description: "Default calendar",
MaxResourceSize: calendarMaxResourceSize,
SupportedComponentSet: calendarSupportedComponentSet,
}
calendars = Calendars{
loaded: false,
changed: false,
lock: sync.Mutex{},
calendars: sync.Map{},
calendarsMetaData: []*caldav.Calendar{},
}
)
type Calendars struct {
loaded bool
changed bool
lock sync.Mutex // load & save
calendars sync.Map // Path -> *Calendar
calendarsMetaData []*caldav.Calendar
}
type Calendar struct {
Changed bool
DirectoryPath string
MetaData *caldav.Calendar
Objects sync.Map // id -> *CalendarObject
}
type CalendarObject struct {
Changed bool
FilePath string
CalendarPath string
Data *caldav.CalendarObject
}
type CalDavBackend struct{}
func (b *CalDavBackend) CurrentUserPrincipal(ctx context.Context) (string, error) {
@ -70,38 +115,38 @@ func (b *CalDavBackend) ListCalendars(ctx context.Context) (calendars []caldav.C
return
}
func (b *CalDavBackend) GetCalendar(ctx context.Context, path string) (calendar *caldav.Calendar, err error) {
logging.LogDebugf("CalDAV GetCalendar -> path: %s", path)
func (b *CalDavBackend) GetCalendar(ctx context.Context, calendarPath string) (calendar *caldav.Calendar, err error) {
logging.LogDebugf("CalDAV GetCalendar -> calendarPath: %s", calendarPath)
// TODO: get calendar
return
}
func (b *CalDavBackend) GetCalendarObject(ctx context.Context, path string, req *caldav.CalendarCompRequest) (calendarObjects *caldav.CalendarObject, err error) {
logging.LogDebugf("CalDAV GetCalendarObject -> path: %s, req: %#v", path, req)
func (b *CalDavBackend) GetCalendarObject(ctx context.Context, calendarPath string, req *caldav.CalendarCompRequest) (calendarObjects *caldav.CalendarObject, err error) {
logging.LogDebugf("CalDAV GetCalendarObject -> calendarPath: %s, req: %#v", calendarPath, req)
// TODO: get calendar object
return
}
func (b *CalDavBackend) ListCalendarObjects(ctx context.Context, path string, req *caldav.CalendarCompRequest) (calendarObjects []caldav.CalendarObject, err error) {
logging.LogDebugf("CalDAV ListCalendarObjects -> path: %s, req: %#v", path, req)
func (b *CalDavBackend) ListCalendarObjects(ctx context.Context, calendarPath string, req *caldav.CalendarCompRequest) (calendarObjects []caldav.CalendarObject, err error) {
logging.LogDebugf("CalDAV ListCalendarObjects -> calendarPath: %s, req: %#v", calendarPath, req)
// TODO: list calendar objects
return
}
func (b *CalDavBackend) QueryCalendarObjects(ctx context.Context, path string, query *caldav.CalendarQuery) (calendarObjects []caldav.CalendarObject, err error) {
logging.LogDebugf("CalDAV QueryCalendarObjects -> path: %s, query: %#v", path, query)
func (b *CalDavBackend) QueryCalendarObjects(ctx context.Context, calendarPath string, query *caldav.CalendarQuery) (calendarObjects []caldav.CalendarObject, err error) {
logging.LogDebugf("CalDAV QueryCalendarObjects -> calendarPath: %s, query: %#v", calendarPath, query)
// TODO: query calendar objects
return
}
func (b *CalDavBackend) PutCalendarObject(ctx context.Context, path string, calendar *ical.Calendar, opts *caldav.PutCalendarObjectOptions) (calendarObject *caldav.CalendarObject, err error) {
logging.LogDebugf("CalDAV PutCalendarObject -> path: %s, opts: %#v", path, opts)
func (b *CalDavBackend) PutCalendarObject(ctx context.Context, calendarPath string, calendar *ical.Calendar, opts *caldav.PutCalendarObjectOptions) (calendarObject *caldav.CalendarObject, err error) {
logging.LogDebugf("CalDAV PutCalendarObject -> calendarPath: %s, opts: %#v", calendarPath, opts)
// TODO: put calendar object
return
}
func (b *CalDavBackend) DeleteCalendarObject(ctx context.Context, path string) (err error) {
logging.LogDebugf("CalDAV DeleteCalendarObject -> path: %s", path)
func (b *CalDavBackend) DeleteCalendarObject(ctx context.Context, calendarPath string) (err error) {
logging.LogDebugf("CalDAV DeleteCalendarObject -> calendarPath: %s", calendarPath)
// TODO: delete calendar object
return
}

View file

@ -47,7 +47,7 @@ const (
CardDavAddressBooksMetaDataFilePath = CardDavHomeSetPath + "/address-books.json"
VCardFileExt = ".vcf"
VCardFileExt = "." + vcard.Extension // .vcf
)
type CardDavPathDepth int
@ -63,14 +63,13 @@ const (
var (
addressBookMaxResourceSize int64 = 0
addressBookContentType = "text/vcard"
addressBookSupportedAddressData = []carddav.AddressDataType{
{
ContentType: addressBookContentType,
ContentType: vcard.MIMEType,
Version: "3.0",
},
{
ContentType: addressBookContentType,
ContentType: vcard.MIMEType,
Version: "4.0",
},
}
@ -100,6 +99,23 @@ var (
ErrorAddressFileExtensionNameInvalid = errors.New("CardDAV: address file extension name is invalid")
)
// ImportVCardFile imports a address book from a vCard file (*.vcf)
func ImportAddressBook(addressBookPath, cardContent string) (addresses []*AddressObject, err error) {
// TODO: Check whether the path is valid (PathDepth: Address)
// TODO: Check whether the address book exists
// TODO: Decode the card content
// TODO: Save the cards to the file system
return
}
// ExportAddressBook exports a address book to a vCard file (*.vcf)
func ExportAddressBook(addressBookPath string) (cardContent string, err error) {
// TODO: Check whether the path is valid (PathDepth: AddressBook)
// TODO: Check whether the address book exists
// TODO: Encode the card content
return
}
// CardDavPath2DirectoryPath converts CardDAV path to absolute path of the file system
func CardDavPath2DirectoryPath(cardDavPath string) string {
return filepath.Join(util.DataDir, "storage", strings.TrimPrefix(cardDavPath, "/"))
@ -791,8 +807,8 @@ func (b *CardDavBackend) CurrentUserPrincipal(ctx context.Context) (string, erro
return CardDavUserPrincipalPath, nil
}
func (b *CardDavBackend) AddressBookHomeSetDirectoryPath(ctx context.Context) (string, error) {
// logging.LogDebugf("CardDAV AddressBookHomeSetDirectoryPath")
func (b *CardDavBackend) AddressBookHomeSetPath(ctx context.Context) (string, error) {
// logging.LogDebugf("CardDAV AddressBookHomeSetPath")
return CardDavHomeSetPath, nil
}

View file

@ -715,7 +715,7 @@ func serveCalDAV(ginServer *gin.Engine) {
}
ginServer.Match(CalDavMethods, "/.well-known/caldav", func(c *gin.Context) {
logging.LogDebugf("CalDAV [/.well-known/caldav]")
// logging.LogDebugf("CalDAV -> [%s] %s", c.Request.Method, c.Request.URL.String())
handler.ServeHTTP(c.Writer, c.Request)
})
@ -771,6 +771,7 @@ func serveCardDAV(ginServer *gin.Engine) {
return
}
}
// TODO: Can't handle Thunderbird's PROPFIND request with prop <current-user-privilege-set/>
handler.ServeHTTP(c.Writer, c.Request)
// logging.LogDebugf("CardDAV <- [%s] %v", c.Request.Method, c.Writer.Status())
})