Skip to content

About

DAV and contacts tooling for practical address book workflows.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

dav-manager

dav-manager is a single-binary Go CLI for cleaning, normalizing, auditing, and reclaiming a Radicale-backed CardDAV address book without turning the job into a GUI slog.

It is built for the real maintenance work:

  • normalize names, phones, and emails
  • move low-value or stressful contacts into structured local buckets with VCF backups
  • reconcile a curated markdown contact table back into CardDAV
  • force stubborn mobile clients to notice contact changes
  • keep photos, UIDs, and refresh behavior under operator control

Install

Fastest local path:

git clone https://github.com/avikalpa/dav-manager.git
cd dav-manager
go build -o bin/dav ./...

Release path:

  • push a semver tag (vX.Y.Z)
  • GitHub Actions publishes Linux, macOS, and Windows binaries on the Releases page

Why this exists

Normal contact apps are decent at casual editing and bad at serious cleanup.

The hard jobs are usually:

  • a few thousand contacts accumulated across years
  • inconsistent names and structured N fields
  • mixed phone formats and duplicate entries
  • contacts you do not want to delete forever, but do not want in the live book
  • DAVx5, Android, or WhatsApp refusing to notice edits cleanly

dav-manager treats the address book like real operator data:

  • fetch it
  • inspect it
  • normalize it
  • move unwanted cards into explicit buckets
  • back everything up in VCF form
  • force downstream clients to refresh when needed

Quick start

  1. Copy .env.example to .env and fill:
    • RADICALE_BASE_URL
    • RADICALE_COLLECTION
    • RADICALE_USER
    • RADICALE_PASS
    • UN_CONTACTS
    • PHOTO_MAP
    • ENABLE_GRAVATAR
  2. Build:
    go build -o bin/dav ./...
  3. Inspect the live address book:
    bin/dav contacts fetch
  4. Inspect the bucketed contacts:
    bin/dav contacts fetch --un-contacts

Core workflows

1. Audit the live book

bin/dav contacts fetch
bin/dav contacts fetch --touch-all

Use --touch-all when you want a broad client refresh after cleanup work.

2. Add or update a real contact

bin/dav contacts add \
  --name "Jane Doe" \
  --emails [email protected] \
  --phones "+1 4803957551" \
  --note "Friend"
bin/dav contacts update \
  --name "Jane Doe" \
  --new-name "Jane D." \
  --phones "+1 4803957551,+91 9876543210"

3. Capture a discovered contact into a bucket (never touches the live book)

For numbers you resolve from a lookup (CallerIDLookup: police, call-centres, delivery, spam) that must NOT enter the phone-synced address book, write an enriched card straight into a bucket:

bin/dav contacts add --bucket calleridlookup \
  --name "Bangalore City Police" \
  --phones "+91 80 22942222" \
  --categories "calleridlookup,police" \
  --org "Karnataka Police" \
  --photo "https://example/dp.jpg" \
  --note "source: calleridlookup 2026-07-24"

The card lands only in $UN_CONTACTS/calleridlookup/…vcf. This path makes no server call and needs no RADICALE_* credentials — it is a pure local write. Promote to the live book later with restore if the contact turns out to be real. The enrichment flags (--categories, --org, --url, --photo) work on the Radicale add path too.

4. Remove a contact without losing it

Delete with an explicit VCF backup:

bin/dav contacts delete \
  --name "Noise Lead" \
  --vcf "$UN_CONTACTS/psychology/noise-lead.vcf"

Or move directly into a bucket:

bin/dav contacts move \
  --name "Vendor X" \
  --bucket corporate \
  --new-name "Vendor X (2019)"

Restore later:

bin/dav contacts restore \
  --name "Vendor X (2019)" \
  --bucket corporate

5. Reconcile from markdown

Keep a table like example-table.md, then apply it:

bin/dav contacts sync \
  --source docs/examples/example-table.md \
  --apply \
  --touch

This is the strongest workflow when you want to review a contact pass in one human-readable document before writing it back.

6. Force mobile clients to notice the cleanup

bin/dav contacts fix-names --apply
bin/dav contacts refresh-uids --apply
bin/dav contacts fetch --touch-all

Use this sequence when Android, DAVx5, or WhatsApp are lagging behind renamed or recreated cards.

7. Add or refresh photos

bin/dav contacts photos --apply --map photo-map.json --gravatar

The photo map is a simple JSON object:

{
  "Jane Doe": "/abs/path/jane.jpg"
}

Buckets and reclaim flow

UN_CONTACTS is the safety valve for the address book. It keeps pruned contacts in explicit folders rather than deleting them into oblivion.

Typical buckets:

  • psychology
  • corporate
  • lost-in-time
  • neutral
  • email_only
  • archive
  • calleridlookup — machine-discovered identities (police / call-centre / delivery / spam), captured by add --bucket calleridlookup and kept out of the phone-synced live book on purpose

This gives you a practical reclaim loop:

  1. fetch the live book
  2. move stale or draining contacts into buckets
  3. normalize what remains
  4. sync from markdown for higher-trust curated passes
  5. force client refresh
  6. periodically clean bucket hygiene

Standards and docs

Release model

  • GitHub Actions builds release binaries for Linux, macOS, and Windows on semver tags
  • Release pages should use curated changelog entries, not autogenerated notes
  • CHANGELOG.md is the second product surface after this README and should explain what got safer, faster, or easier for a serious operator

Development

Requirements:

  • Go 1.21+
  • no Python dependency

Useful commands:

go build -o bin/dav ./...
gofmt -w .

License

About

DAV and contacts tooling for practical address book workflows.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages