feat: CalDAV sync adapter with calendar discovery and delta sync
Add CalDAV protocol implementation: principal discovery, calendar-home-set lookup, calendar listing, and sync-collection delta sync. CalDAVSync parses iCalendar events from CalDAV resources and populates the sync cache. CalDAVSyncProvider implements SyncProvider for account-level orchestration.
This commit is contained in:
21
include/nocal/sync/caldav_account.hpp
Normal file
21
include/nocal/sync/caldav_account.hpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace nocal::sync {
|
||||
|
||||
// CalDAV account configuration.
|
||||
struct CalDAVAccountConfig {
|
||||
std::string server_url;
|
||||
std::string username;
|
||||
std::string password;
|
||||
std::string account_id;
|
||||
std::string display_name;
|
||||
};
|
||||
|
||||
// Derive a deterministic account ID from server URL and username.
|
||||
[[nodiscard]] std::string caldav_account_id(
|
||||
std::string_view server_url, std::string_view username);
|
||||
|
||||
} // namespace nocal::sync
|
||||
52
include/nocal/sync/caldav_sync.hpp
Normal file
52
include/nocal/sync/caldav_sync.hpp
Normal file
@@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
|
||||
#include "nocal/sync/caldav_account.hpp"
|
||||
#include "nocal/sync/http.hpp"
|
||||
#include "nocal/storage/sync_cache.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace nocal::sync {
|
||||
|
||||
// CalDAV calendar listing entry.
|
||||
struct CalDAVCalendar {
|
||||
std::string href;
|
||||
std::string name;
|
||||
std::string description;
|
||||
bool read_only{false};
|
||||
};
|
||||
|
||||
class CalDAVSync {
|
||||
public:
|
||||
CalDAVSync(HttpTransport& transport, storage::SyncCache& cache,
|
||||
const CalDAVAccountConfig& config);
|
||||
|
||||
// Discover principal URL and calendar-home-set.
|
||||
void discover();
|
||||
|
||||
// List calendars under the calendar-home-set.
|
||||
std::vector<CalDAVCalendar> list_calendars();
|
||||
|
||||
// Sync one calendar using sync-collection (delta) or full PROPFIND.
|
||||
// `sync_token` is empty for initial sync. Returns new sync token.
|
||||
std::string sync_calendar(const CalDAVCalendar& calendar,
|
||||
std::string_view sync_token);
|
||||
|
||||
private:
|
||||
HttpTransport& transport_;
|
||||
storage::SyncCache& cache_;
|
||||
CalDAVAccountConfig config_;
|
||||
|
||||
std::string principal_url_;
|
||||
std::string calendar_home_set_;
|
||||
|
||||
std::string send_request(int method, const std::string& url,
|
||||
const std::string& body, const std::vector<HttpHeader>& extra_headers);
|
||||
std::string calendar_resource_url(const std::string& calendar_href) const;
|
||||
std::string stable_calendar_id(const std::string& remote_id) const;
|
||||
std::string stable_event_id(const std::string& calendar_id, const std::string& remote_uid) const;
|
||||
std::string encode_basic_auth() const;
|
||||
};
|
||||
|
||||
} // namespace nocal::sync
|
||||
31
include/nocal/sync/caldav_sync_provider.hpp
Normal file
31
include/nocal/sync/caldav_sync_provider.hpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include "nocal/sync/caldav_account.hpp"
|
||||
#include "nocal/sync/http.hpp"
|
||||
#include "nocal/sync/provider.hpp"
|
||||
|
||||
namespace nocal::storage {
|
||||
class SyncCache;
|
||||
}
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace nocal::sync {
|
||||
|
||||
class CalDAVSyncProvider final : public SyncProvider {
|
||||
public:
|
||||
CalDAVSyncProvider(HttpTransport& transport, storage::SyncCache& cache,
|
||||
CalDAVAccountConfig config);
|
||||
|
||||
std::string_view provider_id() const noexcept override { return "caldav"; }
|
||||
ConnectedAccount connect_account() override;
|
||||
void sync_account(std::string_view account_id, SyncObserver& observer) override;
|
||||
void disconnect_account(std::string_view account_id) override;
|
||||
|
||||
private:
|
||||
HttpTransport& transport_;
|
||||
storage::SyncCache& cache_;
|
||||
CalDAVAccountConfig config_;
|
||||
};
|
||||
|
||||
} // namespace nocal::sync
|
||||
Reference in New Issue
Block a user