atproto-calendar-import is a library and CLI tool for importing calendar events in python & rust
1
2# 📅 atproto-calendar-import
3
4A Rust library and CLI tool for importing calendar events from external providers (Google Calendar, Microsoft Outlook) into the [AT Protocol](https://atproto.com/) ecosystem. Built with [atrium-rs](https://github.com/atrium-rs/atrium) for robust AT Protocol integration.
5
6[](https://rust-lang.org)
7[](LICENSE)
8
9---
10
11## 🌟 Features
12
13- **Multi-Provider Support**: Import from Google Calendar and Microsoft Outlook
14- **OAuth2 Authentication**: Secure authentication flows for external providers
15- **AT Protocol Integration**: Seamless publishing to AT Protocol repositories
16- **Deduplication**: Intelligent event deduplication to prevent duplicates
17- **CLI Interface**: Easy-to-use command-line interface
18- **Configurable**: Flexible configuration options
19- **Error Handling**: Comprehensive error handling with structured error codes
20
21---
22
23## 📦 Repository Structure
24
25```text
26atproto-calendar-import/RUST/
27├── src/
28│ ├── main.rs # CLI binary entry point
29│ ├── lib.rs # Core library exports
30│ ├── auth.rs # OAuth2 + AT Protocol authentication
31│ ├── cli.rs # Command-line interface
32│ ├── dedup.rs # Event deduplication logic
33│ ├── errors.rs # Centralized error definitions
34│ ├── pds.rs # AT Protocol PDS interactions
35│ ├── import/ # External calendar provider integrations
36│ │ ├── mod.rs # Common import types and traits
37│ │ ├── google.rs # Google Calendar API integration
38│ │ └── outlook.rs # Microsoft Outlook/Graph API integration
39│ └── transform/ # Event transformation and validation
40│ ├── mod.rs # Transform module exports
41│ ├── validate.rs # Event validation logic
42│ └── convert.rs # Provider-to-AT Protocol conversion
43├── docs/ # Additional documentation
44├── import/ # Legacy import scripts (deprecated)
45├── transform/ # Legacy transform scripts (deprecated)
46├── target/ # Rust build artifacts
47├── Cargo.toml # Project metadata and dependencies
48├── Cargo.lock # Dependency lock file
49└── README.md # This file
50```
51
52---
53
54## 🚀 Quick Start
55
56### Prerequisites
57
58- **Rust** ≥ 1.70
59- **Cargo** (included with Rust)
60- External calendar API credentials:
61 - Google OAuth2 credentials for Google Calendar
62 - Microsoft Graph API credentials for Outlook
63- AT Protocol account and PDS access
64
65### Installation
66
671. Clone the repository:
68```bash
69git clone <repository-url>
70cd atproto-calendar-import/RUST
71```
72
732. Build the project:
74```bash
75cargo build --release
76```
77
783. Set up environment variables:
79```bash
80# Google Calendar (optional)
81export GOOGLE_CLIENT_ID="your-google-client-id"
82export GOOGLE_CLIENT_SECRET="your-google-client-secret"
83
84# Microsoft Outlook (optional)
85export OUTLOOK_CLIENT_ID="your-outlook-client-id"
86export OUTLOOK_CLIENT_SECRET="your-outlook-client-secret"
87
88# AT Protocol
89export ATP_HANDLE="your-handle.bsky.social"
90export ATP_PASSWORD="your-app-password"
91export ATP_PDS_URL="https://bsky.social" # or your PDS URL
92```
93
94### Basic Usage
95
96Import from Google Calendar:
97```bash
98cargo run -- import-google --interactive
99```
100
101Import from Microsoft Outlook:
102```bash
103cargo run -- import-outlook --interactive
104```
105
106Test AT Protocol connection:
107```bash
108cargo run -- test-connection
109```
110
111Clear deduplication cache:
112```bash
113cargo run -- clear-cache
114```
115
116---
117
118## 🛠️ Development
119
120### Build Commands
121
122| Task | Command | Description |
123|------------------------|------------------------------|---------------------------------------|
124| Build (debug) | `cargo build` | Build in debug mode |
125| Build (release) | `cargo build --release` | Build optimized release binary |
126| Type Check | `cargo check` | Fast type checking without building |
127| Format Code | `cargo fmt` | Format code using rustfmt |
128| Lint Code | `cargo clippy` | Run Clippy linter |
129| Run Tests | `cargo test` | Run all unit and integration tests |
130| Run Specific Test | `cargo test <test_name>` | Run a specific test |
131| Generate Documentation| `cargo doc --open` | Generate and open documentation |
132
133### Testing
134
135```bash
136# Run all tests
137cargo test
138
139# Run tests with output
140cargo test -- --nocapture
141
142# Run integration tests only
143cargo test --test integration
144
145# Run specific test
146cargo test test_google_import
147```
148
149---
150
151## 📋 CLI Commands
152
153### Import Commands
154
155#### `import-google`
156Import events from Google Calendar.
157
158```bash
159cargo run -- import-google [OPTIONS]
160```
161
162**Options:**
163- `-a, --access-token <TOKEN>`: Use existing access token
164- `--interactive`: Start interactive OAuth2 flow
165- `--skip-dedup`: Skip deduplication check
166- `--dry-run`: Preview without publishing to AT Protocol
167
168**Examples:**
169```bash
170# Interactive OAuth2 flow
171cargo run -- import-google --interactive
172
173# Use existing token
174cargo run -- import-google --access-token "ya29.a0..."
175
176# Dry run to preview events
177cargo run -- import-google --interactive --dry-run
178```
179
180#### `import-outlook`
181Import events from Microsoft Outlook.
182
183```bash
184cargo run -- import-outlook [OPTIONS]
185```
186
187**Options:**
188- `-a, --access-token <TOKEN>`: Use existing access token
189- `--interactive`: Start interactive OAuth2 flow
190- `--skip-dedup`: Skip deduplication check
191- `--dry-run`: Preview without publishing to AT Protocol
192
193### Utility Commands
194
195#### `test-connection`
196Test connectivity to AT Protocol PDS.
197
198```bash
199cargo run -- test-connection
200```
201
202#### `clear-cache`
203Clear the deduplication cache for the current user.
204
205```bash
206cargo run -- clear-cache
207```
208
209---
210
211## ⚙️ Configuration
212
213### Environment Variables
214
215#### Required for AT Protocol
216- `ATP_HANDLE`: Your AT Protocol handle (e.g., `alice.bsky.social`)
217- `ATP_PASSWORD`: Your AT Protocol app password
218- `ATP_PDS_URL`: PDS endpoint URL (default: `https://bsky.social`)
219
220#### Optional for Google Calendar
221- `GOOGLE_CLIENT_ID`: Google OAuth2 client ID
222- `GOOGLE_CLIENT_SECRET`: Google OAuth2 client secret
223
224#### Optional for Microsoft Outlook
225- `OUTLOOK_CLIENT_ID`: Microsoft Graph API client ID
226- `OUTLOOK_CLIENT_SECRET`: Microsoft Graph API client secret
227
228#### Optional Configuration
229- `RUST_LOG`: Log level (`trace`, `debug`, `info`, `warn`, `error`)
230- `DATABASE_URL`: PostgreSQL connection string (for persistent deduplication cache)
231
232### OAuth2 Setup
233
234#### Google Calendar API
2351. Go to the [Google Cloud Console](https://console.cloud.google.com/)
2362. Create a new project or select existing one
2373. Enable the Google Calendar API
2384. Create OAuth2 credentials
2395. Set redirect URI to `http://localhost:8080/callback`
240
241#### Microsoft Graph API
2421. Go to [Azure Portal](https://portal.azure.com/)
2432. Navigate to Azure Active Directory > App registrations
2443. Create a new application registration
2454. Add `Calendars.Read` permission
2465. Set redirect URI to `http://localhost:8080/callback`
247
248---
249
250## 🔧 Architecture
251
252### Core Components
253
254- **`auth.rs`**: Handles OAuth2 flows for external providers and AT Protocol authentication
255- **`import/`**: Provider-specific importers (Google, Outlook) that fetch calendar events
256- **`transform/`**: Converts external event formats to AT Protocol lexicon format
257- **`dedup.rs`**: Prevents duplicate events using content hashing and metadata comparison
258- **`pds.rs`**: Publishes events to AT Protocol repositories via atrium-rs
259- **`cli.rs`**: Command-line interface and argument parsing
260
261### Data Flow
262
2631. **Authentication**: OAuth2 flow with calendar provider + AT Protocol session
2642. **Import**: Fetch events from external calendar API
2653. **Transform**: Convert events to AT Protocol format
2664. **Deduplicate**: Check against existing events to prevent duplicates
2675. **Publish**: Create records in AT Protocol repository
268
269### Error Handling
270
271The project uses structured error codes for easy debugging:
272
273- **1xx**: Authentication errors (`OAuth2TokenFailed`, `InvalidAccessToken`, etc.)
274- **2xx**: Import errors (`GoogleApiError`, `OutlookApiError`, etc.)
275- **3xx**: Transform errors (`InvalidDateTimeFormat`, `MissingRequiredField`, etc.)
276- **4xx**: PDS errors (`RecordCreationFailed`, `RepositoryNotFound`, etc.)
277- **5xx**: Internal errors (`DeduplicationError`, `ConfigurationError`, etc.)
278
279---
280
281## 🤝 Contributing
282
2831. Fork the repository
2842. Create a feature branch: `git checkout -b feature/amazing-feature`
2853. Make your changes
2864. Add tests for new functionality
2875. Ensure all tests pass: `cargo test`
2886. Format code: `cargo fmt`
2897. Run linter: `cargo clippy`
2908. Commit changes: `git commit -m 'Add amazing feature'`
2919. Push to branch: `git push origin feature/amazing-feature`
29210. Create a Pull Request
293
294### Code Style
295
296- Follow Rust standard formatting (`cargo fmt`)
297- Add documentation for public APIs
298- Include unit tests for new functionality
299- Use structured error types from `errors.rs`
300- Add tracing instrumentation for important functions
301
302---
303
304## 📝 License
305
306This project is licensed under either of
307
308- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
309- MIT License ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
310
311at your option.
312
313---
314
315## 🔗 Related Projects
316
317- [AT Protocol](https://atproto.com/) - The underlying protocol
318- [atrium-rs](https://github.com/atrium-rs/atrium) - Rust AT Protocol implementation
319- [Bluesky](https://bsky.app/) - Social network built on AT Protocol
320
321---
322
323## 📞 Support
324
325- 📧 **Issues**: [GitHub Issues](../../issues)
326- 📖 **Documentation**: Run `cargo doc --open` for API docs
327- 🌐 **AT Protocol Docs**: https://atproto.com/