Initial skills documentation — 25 categories, all SKILL.md + references + scripts
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
# iCloud CalDAV Configuration
|
||||
|
||||
## Setup
|
||||
|
||||
1. Generate app-specific password at [appleid.apple.com](https://appleid.apple.com) → Security → App-Specific Passwords
|
||||
2. Select "Mail" or "Calendar" service
|
||||
3. Save the 16-char password (format: `xxxx-xxxx-xxxx-xxxx`) to `/root/.config/himalaya/g-germainebrown-icloud-calendar.pass`
|
||||
4. Set file permissions: `chmod 600 /root/.config/himalaya/g-germainebrown-icloud-calendar.pass`
|
||||
|
||||
## Himalaya Config
|
||||
|
||||
Add to `/root/.config/himalaya/config.toml`:
|
||||
|
||||
```toml
|
||||
[accounts.germaine-calendar]
|
||||
backend.type = "caldav"
|
||||
backend.host = "https://caldav.icloud.com"
|
||||
backend.login = "g@germainebrown.com"
|
||||
backend.auth.type = "password"
|
||||
backend.auth.cmd = "cat /root/.config/himalaya/g-germainebrown-icloud-calendar.pass"
|
||||
```
|
||||
|
||||
## Verification Test
|
||||
|
||||
```python
|
||||
import requests
|
||||
with open('/root/.config/himalaya/g-germainebrown-icloud-calendar.pass') as f:
|
||||
pw = f.read().strip()
|
||||
body = '''<?xml version="1.0" encoding="utf-8"?>
|
||||
<d:propfind xmlns:d="DAV:">
|
||||
<d:prop>
|
||||
<d:displayname/>
|
||||
<d:current-user-principal/>
|
||||
</d:prop>
|
||||
</d:propfind>'''
|
||||
r = requests.request('PROPFIND', 'https://caldav.icloud.com/',
|
||||
auth=('g@germainebrown.com', pw),
|
||||
headers={'Content-Type': 'application/xml; charset=utf-8'},
|
||||
data=body, timeout=15)
|
||||
# 207 = Multi-Status (auth OK). 401 = auth failed.
|
||||
```
|
||||
|
||||
## iCloud Calendar Home Discovery
|
||||
|
||||
```python
|
||||
body = '''<?xml version="1.0" encoding="utf-8"?>
|
||||
<d:propfind xmlns:d="DAV:" xmlns:cal="urn:ietf:params:xml:ns:caldav">
|
||||
<d:prop>
|
||||
<cal:calendar-home-set/>
|
||||
</d:prop>
|
||||
</d:propfind>'''
|
||||
r = requests.request('PROPFIND', 'https://caldav.icloud.com/1079451706/principal/',
|
||||
auth=('g@germainebrown.com', pw),
|
||||
headers={'Depth': '0'}, data=body, timeout=15)
|
||||
```
|
||||
|
||||
Returns: `p{xx}-caldav.icloud.com:443/1079451706/calendars/`
|
||||
|
||||
## Pitfalls
|
||||
|
||||
- Apple revokes old app-specific passwords when generating new ones. Always update the `.pass` file after regeneration.
|
||||
- The IMAP-style login test (`p02-imap.mail.me.com:993`) uses a different auth path than CalDAV. A failed IMAP login does NOT mean the password is wrong — use the PROPFIND test against `caldav.icloud.com` instead.
|
||||
- App-specific passwords expire when the Apple ID password is changed or the app is revoked.
|
||||
- Himalaya CalDAV (noted here) is experimental — the `calendar` subcommand may not exist. Use direct Python `requests` for CalDAV operations.
|
||||
Reference in New Issue
Block a user